浅谈iOS11新特性:新增拖拽交互体验

2020-01-21 02:59:45王冬梅

UIDragPreviewTarget主要用来设置动画的起始视图与结束时回归的视图,其中属性方法如下:


/*
初始化方法
container:必须是在window上的view
center:动画起点与终点
transform:进行变换
*/
- (instancetype)initWithContainer:(UIView *)container center:(CGPoint)center transform:(CGAffineTransform)transform;
//同上
- (instancetype)initWithContainer:(UIView *)container center:(CGPoint)center;
//对应属性
@property (nonatomic, readonly) UIView *container;
@property (nonatomic, readonly) CGPoint center;
@property (nonatomic, readonly) CGAffineTransform transform;

UIDragPreviewParameters用来进行拖拽动画的配置,解析如下:


//构造方法并设置路径矩形
- (instancetype)initWithTextLineRects:(NSArray<NSValue /* CGRect */ *> *)textLineRects;
//显示的路径
@property (nonatomic, copy, nullable) UIBezierPath *visiblePath;
//背景色
@property (nonatomic, copy, null_resettable) UIColor *backgroundColor;

我们可以使用任意自定义的视图来展现这个预览动画,如下图所示:

iOS11,拖拽交互,拖拽的交互

十一、使用拖拽操作进行自定义数据的传递

本篇文章到这里,其实基本的内容都已经说完了,虽然比较详细,也可能难免冗余,如果你耐着性子看到了这里,那么我首先钦佩你的毅力并且感谢你的耐心。其实,拖拽交互如果进行只能对系统的提供的数据类型进行操作则应用就局限太多。试想一下,如果我们可以通过拖拽商品来进行购买,拖拽联系人来进行发送,或者在游戏中,拖拽进行卡片的融合,装备的提炼等等这种交互操作是不是会很畅快。最后,我们就来看看如何让自定义的数据类型支持拖拽操作。

首先你需要关注两个协议,NSItemProviderWriting与NSItemProviderReading。Writing协议用来让数据支持提供给数据源,Reading协议让数据支持从数据源读出,用自定义的Person类为例:


#import <Foundation/Foundation.h>
//遵守协议
@interface Person : NSObject<NSItemProviderWriting,NSItemProviderReading>
//自定义内容
@property(nonatomic,strong)NSString * name;
@property(nonatomic,assign)NSUInteger age;
@end


//.m文件
@implementation Person
//数据归档
- (nullable NSProgress *)loadDataWithTypeIdentifier:(NSString *)typeIdentifier
          forItemProviderCompletionHandler:(void (^)(NSData * _Nullable data, NSError * _Nullable error))completionHandler{
  NSProgress * pro = [NSProgress new];
  NSData * data = [NSKeyedArchiver archivedDataWithRootObject:self];
  completionHandler(data,nil);
  return pro;
}

+(NSItemProviderRepresentationVisibility)itemProviderVisibilityForRepresentationWithTypeIdentifier:(NSString *)typeIdentifier{
  return NSItemProviderRepresentationVisibilityAll;
}

- (NSItemProviderRepresentationVisibility)itemProviderVisibilityForRepresentationWithTypeIdentifier:(NSString *)typeIdentifier{
  return NSItemProviderRepresentationVisibilityAll;
}
//提供一个标识符
+(NSArray<NSString *> *)writableTypeIdentifiersForItemProvider{
  return @[@"object"];
}
-(NSArray<NSString *> *)writableTypeIdentifiersForItemProvider{
  return @[@"object"];
}

- (instancetype)initWithCoder:(NSCoder *)coder
{
  self = [super init];
  if (self) {
    self.name = [coder decodeObjectForKey:@"name"];
    self.age = [coder decodeIntegerForKey:@"age"];
  }
  return self;
}

- (void)encodeWithCoder:(NSCoder *)aCoder{
  [aCoder encodeObject:self.name forKey:@"name"];
  [aCoder encodeInteger:self.age forKey:@"age"];
}
//这两个是读协议
+(NSArray<NSString *> *)readableTypeIdentifiersForItemProvider{
  return @[@"object"];
}
//解归档返回
+ (nullable instancetype)objectWithItemProviderData:(NSData *)data
                   typeIdentifier:(NSString *)typeIdentifier
                       error:(NSError **)outError{
  Person * p = [NSKeyedUnarchiver unarchiveObjectWithData:data];
  return p;
}
@end