1、Drag and Drop简介
Drag and Drop是iOS11的新特性,可以将文本、图片进行拖拽到不同app中,实现数据的传递。只不过只能在iPad上使用,iPhone上只能app内部拖拽!
2、简单使用
相关代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#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 ()<UIDragInteractionDelegate,UIDropInteractionDelegate> @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<UIDragItem *> *)dragInteraction:(UIDragInteraction *)interaction itemsForBeginningSession:(id<UIDragSession>)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<UIDragSession>)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<UIDragAnimating>)animator session:(id<UIDragSession>)session{ NSLog(@"33333----"); [animator addCompletion:^(UIViewAnimatingPosition finalPosition) { if (finalPosition == UIViewAnimatingPositionEnd) { self.img.alpha = 0.5; } }]; } //drag将要结束时调用 - (void)dragInteraction:(UIDragInteraction *)interaction session:(id<UIDragSession>)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<UIDragAnimating>)animator{ NSLog(@"55555----"); [animator addAnimations:^{ self.img.alpha = .1; }]; } //drag已经结束时调用 - (void)dragInteraction:(UIDragInteraction *)interaction session:(id<UIDragSession>)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<UIDropSession>)session{ if(session.localDragSession == nil){//说明数据来自外界 } return [session canLoadObjectsOfClass:[UIImage class]]; } //第二次判断是否可以接收 无法接收用UIDropOperationCancel - (UIDropProposal *)dropInteraction:(UIDropInteraction *)interaction sessionDidUpdate:(id<UIDropSession>)session{ UIDropOperation opera = session.localDragSession? UIDropOperationCopy:UIDropOperationCancel; return [[UIDropProposal alloc] initWithDropOperation:opera]; } //取出来自drag的数据 - (void)dropInteraction:(UIDropInteraction *)interaction performDrop:(id<UIDropSession>)session{ if (session.localDragSession) { NSProgress *pregesss = [session loadObjectsOfClass:[UIImage class] completion:^(NSArray<__kindof id<NSItemProviderReading>> * _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 <NSObject> - (void)addAnimations:(void (^)(void))animations; - (void)addCompletion:(void (^)(UIViewAnimatingPosition finalPosition))completion; @end UIKIT_EXTERN API_AVAILABLE(ios(11.0)) API_UNAVAILABLE(watchos, tvos) @interface UIDragInteraction : NSObject <UIInteraction> - (instancetype)initWithDelegate:(id<UIDragInteractionDelegate>)delegate NS_DESIGNATED_INITIALIZER; - (instancetype)init NS_UNAVAILABLE; + (instancetype)new NS_UNAVAILABLE; @property (nonatomic, nullable, readonly, weak) id<UIDragInteractionDelegate> delegate; @property (nonatomic) BOOL allowsSimultaneousRecognitionDuringLift; @property (nonatomic, getter=isEnabled) BOOL enabled; @property (class, nonatomic, readonly, getter=isEnabledByDefault) BOOL enabledByDefault; @end API_AVAILABLE(ios(11.0)) API_UNAVAILABLE(watchos, tvos) @protocol UIDragInteractionDelegate <NSObject> @required //提供数据源 长按UI开始拖拽 - (NSArray<UIDragItem *> *)dragInteraction:(UIDragInteraction *)interaction itemsForBeginningSession:(id<UIDragSession>)session; @optional //提供UITargetedDragPreview的相关信息 长按UI是有个lift(UI举起效果,系统自动生成) //返回nil 没有效果; 不实现该方法 interaction.view自动生成UITargetedDragPreview - (nullable UITargetedDragPreview *)dragInteraction:(UIDragInteraction *)interaction previewForLiftingItem:(UIDragItem *)item session:(id<UIDragSession>)session; //drag发生时调用 - (void)dragInteraction:(UIDragInteraction *)interaction willAnimateLiftWithAnimator:(id<UIDragAnimating>)animator session:(id<UIDragSession>)session; //将要开始drag - (void)dragInteraction:(UIDragInteraction *)interaction sessionWillBegin:(id<UIDragSession>)session; //是否允许数据移动 app内移动有效,跨app总是复制数据 - (BOOL)dragInteraction:(UIDragInteraction *)interaction sessionAllowsMoveOperation:(id<UIDragSession>)session; //是否允许跨应用程序进行drag ipad - (BOOL)dragInteraction:(UIDragInteraction *)interaction sessionIsRestrictedToDraggingApplication:(id<UIDragSession>)session; //设置预览视图是否显示原始大小 - (BOOL)dragInteraction:(UIDragInteraction *)interaction prefersFullSizePreviewsForSession:(id<UIDragSession>)session; //已经结束移动 - (void)dragInteraction:(UIDragInteraction *)interaction sessionDidMove:(id<UIDragSession>)session; //drag将要结束时调用 - (void)dragInteraction:(UIDragInteraction *)interaction session:(id<UIDragSession>)session willEndWithOperation:(UIDropOperation)operation; //drag已经结束时调用 - (void)dragInteraction:(UIDragInteraction *)interaction session:(id<UIDragSession>)session didEndWithOperation:(UIDropOperation)operation; //拖拽源进行了放置操作后调用 - (void)dragInteraction:(UIDragInteraction *)interaction sessionDidTransferItems:(id<UIDragSession>)session; //设置是否允许向拖拽中的项目添加数据 返回数据载体数组 drag时点击拖拽的组件调用 - (NSArray<UIDragItem *> *)dragInteraction:(UIDragInteraction *)interaction itemsForAddingToSession:(id<UIDragSession>)session withTouchAtPoint:(CGPoint)point; //设置允许进行拖拽中追加数据的拖拽行为会话 - (nullable id<UIDragSession>)dragInteraction:(UIDragInteraction *)interaction sessionForAddingItems:(NSArray<id<UIDragSession>> *)sessions withTouchAtPoint:(CGPoint)point; //将要向拖拽组件中追加数据时调用 - (void)dragInteraction:(UIDragInteraction *)interaction session:(id<UIDragSession>)session willAddItems:(NSArray<UIDragItem *> *)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<UIDragAnimating>)animator;
UIDropInteraction和Delegate方法:
@protocol UIDragAnimating, UIDropInteractionDelegate, UIDropSession; @class UIDragItem, UITargetedDragPreview; UIKIT_EXTERN API_AVAILABLE(ios(11.0)) API_UNAVAILABLE(watchos, tvos) @interface UIDropInteraction : NSObject <UIInteraction> - (instancetype)initWithDelegate:(id<UIDropInteractionDelegate>)delegate NS_DESIGNATED_INITIALIZER; - (instancetype)init NS_UNAVAILABLE; + (instancetype)new NS_UNAVAILABLE; @property (nonatomic, nullable, readonly, weak) id<UIDropInteractionDelegate> delegate; @property (nonatomic, assign) BOOL allowsSimultaneousDropSessions; @end typedef 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 <NSCopying> - (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; @end API_AVAILABLE(ios(11.0)) API_UNAVAILABLE(watchos, tvos) @protocol UIDropInteractionDelegate <NSObject> @optional //是否可以处理来自Drag的数据 - (BOOL)dropInteraction:(UIDropInteraction *)interaction canHandleSession:(id<UIDropSession>)session; //Drag的UI元素进入Drop的区域 - (void)dropInteraction:(UIDropInteraction *)interaction sessionDidEnter:(id<UIDropSession>)session; //第二次判断是否可以接收 无法接收用UIDropOperationCancel - (UIDropProposal *)dropInteraction:(UIDropInteraction *)interaction sessionDidUpdate:(id<UIDropSession>)session; //Drag的UI元素离开Drop的区域 - (void)dropInteraction:(UIDropInteraction *)interaction sessionDidExit:(id<UIDropSession>)session; //取出来自drag的数据 - (void)dropInteraction:(UIDropInteraction *)interaction performDrop:(id<UIDropSession>)session; //drop结束 - (void)dropInteraction:(UIDropInteraction *)interaction concludeDrop:(id<UIDropSession>)session; //整个Drag和Drop结束 - (void)dropInteraction:(UIDropInteraction *)interaction sessionDidEnd:(id<UIDropSession>)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<UIDragAnimating>)animator; @end