1、Drag and Drop简介
Drag and Drop是iOS11的新特性,可以将文本、图片进行拖拽到不同app中,实现数据的传递。只不过只能在iPad上使用,iPhone上只能app内部拖拽!
2、简单使用
相关代码:
#import "ViewController.h"#define CScreenWidth [[UIScreen mainScreen] bounds].size.width#define CScreenHeight [[UIScreen mainScreen] bounds].size.height#define ScreenHeight self.view.frame.size.height#define ScreenWidth self.view.frame.size.width@interface ViewController ()@property (nonatomic, strong)UIImageView *img;@property (nonatomic, strong)UIImageView *img2;@end@implementation ViewController- (void)viewDidLoad { [super viewDidLoad]; self.img =[[UIImageView alloc] initWithImage:[UIImage imageNamed:@"pic4"]]; self.img.frame = CGRectMake(20, 40, CScreenWidth-40, 200); self.img.userInteractionEnabled = YES; [self.view addSubview:self.img]; //Drag发送数据,Drop接收数据 UIDragInteraction *dragInter = [[UIDragInteraction alloc] initWithDelegate:self]; dragInter.enabled = YES; [self.img addInteraction:dragInter]; [self.view addInteraction:[[UIDropInteraction alloc] initWithDelegate:self]]; self.img2 =[[UIImageView alloc] init]; self.img2.frame = CGRectMake(20, CScreenHeight-250, CScreenWidth-40, 200); self.img2.userInteractionEnabled = YES; [self.view addSubview:self.img2]; }#pragma mark -UIDragInteractionDelegate//提供数据源 开始拖拽- (NSArray *)dragInteraction:(UIDragInteraction *)interaction itemsForBeginningSession:(id )session{ NSLog(@"11111----"); self.img2.image = nil; NSItemProvider *item = [[NSItemProvider alloc] initWithObject:self.img.image]; UIDragItem *dragItem = [[UIDragItem alloc] initWithItemProvider:item]; dragItem.localObject = self.img.image; return @[dragItem];}//提供preview相关信息- (nullable UITargetedDragPreview *)dragInteraction:(UIDragInteraction *)interaction previewForLiftingItem:(UIDragItem *)item session:(id )session{ NSLog(@"22222----"); UIDragPreviewParameters *parameters = [[UIDragPreviewParameters alloc] init]; //设置蒙版mask parameters.visiblePath = [UIBezierPath bezierPathWithRoundedRect:self.img.bounds cornerRadius:20]; //设置在哪个父视图和哪个位置展示 UIDragPreviewTarget *target = [[UIDragPreviewTarget alloc] initWithContainer:self.img.superview center:self.img.center]; UITargetedDragPreview *dragePreview = [[UITargetedDragPreview alloc] initWithView:interaction.view parameters:parameters target:target]; return dragePreview;}//drag进行时- (void)dragInteraction:(UIDragInteraction *)interaction willAnimateLiftWithAnimator:(id )animator session:(id )session{ NSLog(@"33333----"); [animator addCompletion:^(UIViewAnimatingPosition finalPosition) { if (finalPosition == UIViewAnimatingPositionEnd) { self.img.alpha = 0.5; } }];}//drag将要结束时调用- (void)dragInteraction:(UIDragInteraction *)interaction session:(id )session willEndWithOperation:(UIDropOperation)operation{ NSLog(@"44444----"); [UIView animateWithDuration:0.5 animations:^{ self.img.alpha = 1; }];}//drag动画将要取消时- (void)dragInteraction:(UIDragInteraction *)interaction item:(UIDragItem *)item willAnimateCancelWithAnimator:(id )animator{ NSLog(@"55555----"); [animator addAnimations:^{ self.img.alpha = .1; }];}//drag已经结束时调用- (void)dragInteraction:(UIDragInteraction *)interaction session:(id )session didEndWithOperation:(UIDropOperation)operation{ NSLog(@"66666----"); [UIView animateWithDuration:0.5 animations:^{ self.img.alpha = 1; }];}#pragma mark --UIDropInteractionDelegate//是否可以接收来自Drag数据- (BOOL)dropInteraction:(UIDropInteraction *)interaction canHandleSession:(id )session{ if(session.localDragSession == nil){ //说明数据来自外界 } return [session canLoadObjectsOfClass:[UIImage class]];}//第二次判断是否可以接收 无法接收用UIDropOperationCancel- (UIDropProposal *)dropInteraction:(UIDropInteraction *)interaction sessionDidUpdate:(id )session{ UIDropOperation opera = session.localDragSession? UIDropOperationCopy:UIDropOperationCancel; return [[UIDropProposal alloc] initWithDropOperation:opera];}//取出来自drag的数据- (void)dropInteraction:(UIDropInteraction *)interaction performDrop:(id )session{ if (session.localDragSession) { NSProgress *pregesss = [session loadObjectsOfClass:[UIImage class] completion:^(NSArray<__kindof id > * _Nonnull objects) { // 回调的代码块默认就在主线程 for (id objc in objects) { UIImage *image = (UIImage *)objc; if (image) { self.img2.image = image; } } }]; }}@end
3、有关方法简介
UIDragInteraction和Delegate方法:
@protocol UIDragInteractionDelegate, UIDragSession;@class UIDragItem, UITargetedDragPreview;API_AVAILABLE(ios(11.0)) API_UNAVAILABLE(watchos, tvos) @protocol UIDragAnimating- (void)addAnimations:(void (^)(void))animations;- (void)addCompletion:(void (^)(UIViewAnimatingPosition finalPosition))completion;@endUIKIT_EXTERN API_AVAILABLE(ios(11.0)) API_UNAVAILABLE(watchos, tvos) @interface UIDragInteraction : NSObject - (instancetype)initWithDelegate:(id )delegate NS_DESIGNATED_INITIALIZER;- (instancetype)init NS_UNAVAILABLE;+ (instancetype)new NS_UNAVAILABLE;@property (nonatomic, nullable, readonly, weak) id delegate;@property (nonatomic) BOOL allowsSimultaneousRecognitionDuringLift;@property (nonatomic, getter=isEnabled) BOOL enabled;@property (class, nonatomic, readonly, getter=isEnabledByDefault) BOOL enabledByDefault;@endAPI_AVAILABLE(ios(11.0)) API_UNAVAILABLE(watchos, tvos) @protocol UIDragInteractionDelegate @required//提供数据源 长按UI开始拖拽- (NSArray *)dragInteraction:(UIDragInteraction *)interaction itemsForBeginningSession:(id )session;@optional//提供UITargetedDragPreview的相关信息 长按UI是有个lift(UI举起效果,系统自动生成)//返回nil 没有效果; 不实现该方法 interaction.view自动生成UITargetedDragPreview- (nullable UITargetedDragPreview *)dragInteraction:(UIDragInteraction *)interaction previewForLiftingItem:(UIDragItem *)item session:(id )session;//drag发生时调用- (void)dragInteraction:(UIDragInteraction *)interaction willAnimateLiftWithAnimator:(id )animator session:(id )session;//将要开始drag- (void)dragInteraction:(UIDragInteraction *)interaction sessionWillBegin:(id )session;//是否允许数据移动 app内移动有效,跨app总是复制数据- (BOOL)dragInteraction:(UIDragInteraction *)interaction sessionAllowsMoveOperation:(id )session;//是否允许跨应用程序进行drag ipad- (BOOL)dragInteraction:(UIDragInteraction *)interaction sessionIsRestrictedToDraggingApplication:(id )session;//设置预览视图是否显示原始大小- (BOOL)dragInteraction:(UIDragInteraction *)interaction prefersFullSizePreviewsForSession:(id )session;//已经结束移动- (void)dragInteraction:(UIDragInteraction *)interaction sessionDidMove:(id )session;//drag将要结束时调用- (void)dragInteraction:(UIDragInteraction *)interaction session:(id )session willEndWithOperation:(UIDropOperation)operation;//drag已经结束时调用- (void)dragInteraction:(UIDragInteraction *)interaction session:(id )session didEndWithOperation:(UIDropOperation)operation;//拖拽源进行了放置操作后调用- (void)dragInteraction:(UIDragInteraction *)interaction sessionDidTransferItems:(id )session;//设置是否允许向拖拽中的项目添加数据 返回数据载体数组 drag时点击拖拽的组件调用- (NSArray *)dragInteraction:(UIDragInteraction *)interaction itemsForAddingToSession:(id )session withTouchAtPoint:(CGPoint)point;//设置允许进行拖拽中追加数据的拖拽行为会话- (nullable id )dragInteraction:(UIDragInteraction *)interaction sessionForAddingItems:(NSArray > *)sessions withTouchAtPoint:(CGPoint)point;//将要向拖拽组件中追加数据时调用- (void)dragInteraction:(UIDragInteraction *)interaction session:(id )session willAddItems:(NSArray *)items forInteraction:(UIDragInteraction *)addingInteraction;//设置拖拽动作取消的视图动画 返回nil则消除动画- (nullable UITargetedDragPreview *)dragInteraction:(UIDragInteraction *)interaction previewForCancellingItem:(UIDragItem *)item withDefault:(UITargetedDragPreview *)defaultPreview;//drag动画将要取消时调用- (void)dragInteraction:(UIDragInteraction *)interaction item:(UIDragItem *)item willAnimateCancelWithAnimator:(id )animator;
UIDropInteraction和Delegate方法:
@protocol UIDragAnimating, UIDropInteractionDelegate, UIDropSession;@class UIDragItem, UITargetedDragPreview;UIKIT_EXTERN API_AVAILABLE(ios(11.0)) API_UNAVAILABLE(watchos, tvos) @interface UIDropInteraction : NSObject- (instancetype)initWithDelegate:(id )delegate NS_DESIGNATED_INITIALIZER;- (instancetype)init NS_UNAVAILABLE;+ (instancetype)new NS_UNAVAILABLE;@property (nonatomic, nullable, readonly, weak) id delegate;@property (nonatomic, assign) BOOL allowsSimultaneousDropSessions;@endtypedef NS_ENUM(NSUInteger, UIDropOperation) { UIDropOperationCancel = 0, UIDropOperationForbidden = 1, UIDropOperationCopy = 2, UIDropOperationMove = 3,} API_AVAILABLE(ios(11.0)) API_UNAVAILABLE(watchos, tvos);UIKIT_EXTERN API_AVAILABLE(ios(11.0)) API_UNAVAILABLE(watchos, tvos) @interface UIDropProposal : NSObject - (instancetype)initWithDropOperation:(UIDropOperation)operation NS_DESIGNATED_INITIALIZER;- (instancetype)init NS_UNAVAILABLE;+ (instancetype)new NS_UNAVAILABLE;@property (nonatomic, readonly) UIDropOperation operation;@property (nonatomic, getter=isPrecise) BOOL precise;@property (nonatomic) BOOL prefersFullSizePreview;@endAPI_AVAILABLE(ios(11.0)) API_UNAVAILABLE(watchos, tvos) @protocol UIDropInteractionDelegate @optional//是否可以处理来自Drag的数据- (BOOL)dropInteraction:(UIDropInteraction *)interaction canHandleSession:(id )session;//Drag的UI元素进入Drop的区域- (void)dropInteraction:(UIDropInteraction *)interaction sessionDidEnter:(id )session;//第二次判断是否可以接收 无法接收用UIDropOperationCancel- (UIDropProposal *)dropInteraction:(UIDropInteraction *)interaction sessionDidUpdate:(id )session;//Drag的UI元素离开Drop的区域- (void)dropInteraction:(UIDropInteraction *)interaction sessionDidExit:(id )session;//取出来自drag的数据
NSLog(@"%f,%f",[session locationInView:self.view].x,[session locationInView:self.view].y)
- (void)dropInteraction:(UIDropInteraction *)interaction performDrop:(id)session;//drop结束- (void)dropInteraction:(UIDropInteraction *)interaction concludeDrop:(id )session;//整个Drag和Drop结束- (void)dropInteraction:(UIDropInteraction *)interaction sessionDidEnd:(id )session;//手指松开,控制Drag Preview 如何自然的过渡到Drop之后的Preview- (nullable UITargetedDragPreview *)dropInteraction:(UIDropInteraction *)interaction previewForDroppingItem:(UIDragItem *)item withDefault:(UITargetedDragPreview *)defaultPreview;//手指松开Drop时,控制Drop区域的其他UI元素如何展示动画- (void)dropInteraction:(UIDropInteraction *)interaction item:(UIDragItem *)item willAnimateDropWithAnimator:(id )animator;@end