在使用PC进行操作时,你一定遇到过这样的场景,可以将图片直接拖入聊天软件进行发送,可以将文档、音乐、视频文件等文件拖入相应应用程序直接进行使用。这种拖拽操作交互极大的方便了电脑的使用。在iOS11
中,你可以在iPhone
或iPad
上构建这种交互体验!
拖拽操作在iPad
上是支持跨应用程序的,你可以从一个应用中拖取项目,通过Home
键回到主界面并且打开另一个应用程序,然后将被拖拽的项目传递给这个应用程序中。在iPhone
上,拖拽操作只支持当前应用程序内,你可以将某个元素从一个界面拖拽到另一个,这种维度的操作可以给设计人员更大的灵活性。接下来由浅入深讲解拖拽操作的使用法法
拖拽源
对于拖拽操作,至少要有两个组件,一个组件作为拖拽源用来提供数据,一个组件作为拖拽目的用来接收数据,当前,同一个组件既可以是拖拽源也可以是拖拽目的。首先我们先来看拖拽源,在UIKit框架中,iOS11默认实现了一些组件可以作为拖拽源, 例如UITextField、UITextView、UITableView
和UICollectionView
等。文本组件默认支持拖拽操作进行文本的传递,对于列表组件则默认支持元素的拖拽。例如,在UITextField
选中的文案中进行拖拽,可以将文字拖拽出来,效果如下图:
所有继承自UIView的控件都可以作为拖拽源,让其成为拖拽源其实也十分简单,只需要3步:
-
创建一个UIDragInteraction行为对象。(并将其
isEnabled
属性设为true
, 在ipad
是默认开启的, 在iphone
时是默认关闭的, 如果关闭不能拖拽) -
设置UIDragInteraction对象的代理并实现相应方法。
-
将UIDragInteraction对象添加到指定View上。
代码如下:
1.创建拖拽行为的对象,并设置相关属性
1 |
|
2.创建拖拽view(此处我使用xib创建),并为其添加拖拽行为
1 |
|
3.实现提供数据源的代理方法 UIDragInteractionDelegate
1 |
|
下面简单介绍一下实现拖拽对象使用的几个类:
UIDragInteraction类
所有可以接收拖拽行为的组件都必须通过这个类实现,其继承自 UIInteraction
, 这个类中属性意义列举如下
1 |
|
UIDragInteractionDelegate协议
用来处理拖拽源的行为与数据。其中定义了一个必须实现的方法和许多可选实现的方法。解析如下:
1 |
|
如下是拖拽的声明周期回调
1 |
|
添加项目到已经有现有的拖动
1 |
|
拖拽取消动画
1 |
|
放置目的地
拖拽源是数据的提供者,放置目的地就是数据的接收者。前面我们也实验过,将自定义的拖拽源拖拽进UITextField后,文本框中会自动填充我们提供的文本数据。同样,对于任何自定义的UIView视图,我们也可以让其成为放置目的地,需要完成如下3步:
-
创建一个UIDropInteraction行为对象。
-
设置UIDropInteraction对象的代理并实现协议方法。
-
将其添加到自定义的视图中。
代码如下:
1 |
|
关于UIDropInteraction类
与UIDragInteraction类类似,这个类的作用是让组件有相应放置操作的能力。其属性和方法很少, 非常简单.
UIDropInteractionDelegate协议
UIDropInteractionDelegate协议中所定义的方法全部是可选实现的,其用来处理用户放置交互行为。
/* 是否响应放置行为, 默认值为true
* 放回true: 其他一些列的代理方法会被调用
* 返回false:会略这次放置行为
* 此方法应常用来检验此session是否包含代理能处理的items, 方法如下:-hasItemsConformingToTypeIdentifiers:
, -canLoadObjectsOfClass:
, etc.
*/
optional public func dropInteraction(_ interaction: UIDropInteraction, canHandle session: UIDropSession) -> Bool
1 |
|
下面这些方法用来自定义放置动画
1 |
|
拖拽数据载体UIDragItem类
UIDragItem类用来承载要传递的数据. 其通过NSItemProvider类来进行构建,传递的数据类型是有严格规定的,必须遵守一定的协议,系统的NSString,NSAttributeString,NSURL,UIColor和UIImage是默认支持的,你可以直接传递这些数据。 UIDragItem中提供的属性方法:
1 |
|
UIDropSession与UIDragSession
在与拖拽交互相关的接口中,这两个是面向协议编程的绝佳范例,首先在UIKit框架中只定义了这两个协议,而并没有相关的实现类,在拖拽行为的相关回调接口中,很多id类型的参数都遵守了这个协议,我们无需知道是哪个类实现的,直接进行使用即可:
UIDragSession
/* 设置要传递的额外信息 只有在同个APP内可见1 |
|
UIDropSession
继承于UIDragDropSession(提供基础数据), NSProgressReporting(提供数据读取进度)
/* 原始的dragSesstion会话 如果是跨应用的 则为nil */
1 |
|
UIDragDropSession: 以上两个session的基类,其属性和方法如下所示
1 |
|
交互预览类UITargetedDragPreview
UITargetedDragPreview专门用来处理拖放交互过程中的动画与预览视图
1 |
|
UIDragPreviewTarget
主要用来设置动画的起始视图与结束时回归的视图,介绍如下:
1 |
|
UIDragPreviewParameters
用来进行拖拽动画的配置,解析如下:
1 |
|
本文参考资料: