简单使用 iOS 的 Drag and Drop

理解 Drag and Drop

概述

Drag and Drop 是 Apple 在 WWDC 2017 上提出的 iOS 11 的新特性,它可以让我们很方便的实现“拖拽”功能,例如拖拽文本、图片和其他物体,iOS 11 的内建 App 中已经全面的应用了这个特性,你可以把 Photos 中的照片拖拽到正在编辑的邮件中,得益于 Multi-Touch,我们在拖拽的过程中可以正常进行其他的操作,整个拖拽过程是在子线程中完成的,所以你可以同时选择多张照片拖拽,然后按下 Home 键回到 Home Screen,此时你拖拽的照片依然处于悬浮状态,只要你不松手,然后打开 Mail,在编辑框中放开那一堆照片,这些照片就会乖乖的按顺序粘贴到编辑框中了~

简单使用 iOS 的 Drag and Drop_第1张图片
在分屏模式下使用 Drag and Drop

注意,跨 App 的 Drag and Drop 只能在 iPad 上使用,iPhone 只支持 App 内的 Drag and Drop。

如何使用

被拖拽的 Object 都来自被称为 源 app 的地方,而拖拽的目标地点被称为 目标 app,拖拽使用一个系统提供的手势服务被称作 Drag Activity,一个 Drag Session 由系统管理并由用户操作。
当拖拽的动作正在执行时,用户可以执行其他操作,例如调出 Dock 栏、按下 Home 键、创造分屏等。

系统将自动处理所有安全问题,你无需为安全性考虑,也不用在 Info.plist 中添加任何键值。

Coding

在一切开始前,你需要创建一个工程,然后让默认的 ViewController 遵守 Drag 操作需要的 UIDragInteractionDelegate 协议,和 Drop 操作需要的 UIDropInteractionDelegate,或是任何你准备用来使能 Drag and Drop 的视图控制器。

把 Photos 中或任何一处的照片拖拽到你的 App 中

要完成这个操作,你至少要让你的控制器遵守 UIDropInteractionDelegate 协议。

在 UITextView、UITableView 和 UICollectionView 中,分别有属于它们自己的特别定制的协议,详情见他们的 Reference,这里暂不做介绍

让一个 View 成为 Drop 目标(Drop destination)

所有 UIView 或子类的对象都可以成为 Drop 目标,你需要执行这三个步骤:
1.创建一个 UIDropInteraction 对象
2.指定 drop interaction 的代理,所需要的协议是 UIDropInteractionDelegate
3.把 drop interaction 对象添加给 Drop destination 的 interactions 属性

上面的步骤,你用如下代码就可以完成:

/// 把这个方法放在视图控制器中方便调用
/// 这里的 view 指你自己创建的 drop destination
func customEnableDropping(on view: UIView, dropInteractionDelegate: UIDropInteractionDelegate) {
    let dropInteraction = UIDropInteraction(delegate: dropInteractionDelegate)
    view.addInteraction(dropInteraction)
}

告诉系统和用户,拖拽的物体能否支持 Drop

当用户把某一个物体拖拽到 Destination App 的 destination view 里而并未放开手指时,系统会调用 dropInteraction(_:canHandle:) 代理方法,这个方法有一个 Bool 类型的返回值,用来告诉系统这个物体能否支持你的 App,如果支持,在 UI 上会显示一个原谅色的 + 号提醒用户可以在这里 let them go。

func dropInteraction(_ interaction: UIDropInteraction, canHandle session: UIDropSession) -> Bool {
    // 用来确定传入的物体是否是 UIImage 对象
    return session.canLoadObjects(ofClass: [UIImage.self])
}

提供一个必须的 Drop 建议(Proposal)

为了从一个 Session 中接受数据,你必须实现 dropInteraction(_:sessionDidUpdate) 的协议方法。

func dropInteraction(_ interaction: UIDropInteraction, sessionDidUpdate session: UIDropSession) -> UIDropProposal {
        // 让系统“拷贝”这个项目
        return UIDropProposal(operation: .copy)
}

当用户成功 Drop 后,把 Drop 的 Items 提取出来

func dropInteraction(_ interaction: UIDropInteraction, performDrop session: UIDropSession) {
    // 读取 items 数组并处理它们
    session.loadObjects(ofClass: UIImage.self) { imageItems in
        let images = imageItems as! [UIImage]
        self.imageView.image = images.first
    }
}

现在,你应该拥有一个可以获取来自其他地方的照片的 App 了,而且是通过拖拽的方式!

最後で

接下来会慢慢更新 Drag and Drop 特性其他的部分,例如让你的 App 元素变得可以 Drag,而且还能够拖拽到别的地方,甚至另一个 App

你可能感兴趣的:(简单使用 iOS 的 Drag and Drop)