簡(jiǎn)單使用 iOS 的 Drag and Drop

理解 Drag and Drop

概述

Drag and Drop 是 Apple 在 WWDC 2017 上提出的 iOS 11 的新特性,它可以讓我們很方便的實(shí)現(xiàn)“拖拽”功能,例如拖拽文本、圖片和其他物體,iOS 11 的內(nèi)建 App 中已經(jīng)全面的應(yīng)用了這個(gè)特性,你可以把 Photos 中的照片拖拽到正在編輯的郵件中,得益于 Multi-Touch,我們?cè)谕献У倪^(guò)程中可以正常進(jìn)行其他的操作,整個(gè)拖拽過(guò)程是在子線程中完成的,所以你可以同時(shí)選擇多張照片拖拽,然后按下 Home 鍵回到 Home Screen,此時(shí)你拖拽的照片依然處于懸浮狀態(tài),只要你不松手,然后打開 Mail,在編輯框中放開那一堆照片,這些照片就會(huì)乖乖的按順序粘貼到編輯框中了~

在分屏模式下使用 Drag and Drop

注意,跨 App 的 Drag and Drop 只能在 iPad 上使用,iPhone 只支持 App 內(nèi)的 Drag and Drop。

如何使用

被拖拽的 Object 都來(lái)自被稱為 源 app 的地方,而拖拽的目標(biāo)地點(diǎn)被稱為 目標(biāo) app,拖拽使用一個(gè)系統(tǒng)提供的手勢(shì)服務(wù)被稱作 Drag Activity,一個(gè) Drag Session 由系統(tǒng)管理并由用戶操作。
當(dāng)拖拽的動(dòng)作正在執(zhí)行時(shí),用戶可以執(zhí)行其他操作,例如調(diào)出 Dock 欄、按下 Home 鍵、創(chuàng)造分屏等。

系統(tǒng)將自動(dòng)處理所有安全問(wèn)題,你無(wú)需為安全性考慮,也不用在 Info.plist 中添加任何鍵值。

Coding

在一切開始前,你需要?jiǎng)?chuàng)建一個(gè)工程,然后讓默認(rèn)的 ViewController 遵守 Drag 操作需要的 UIDragInteractionDelegate 協(xié)議,和 Drop 操作需要的 UIDropInteractionDelegate,或是任何你準(zhǔn)備用來(lái)使能 Drag and Drop 的視圖控制器。

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

要完成這個(gè)操作,你至少要讓你的控制器遵守 UIDropInteractionDelegate 協(xié)議。

在 UITextView、UITableView 和 UICollectionView 中,分別有屬于它們自己的特別定制的協(xié)議,詳情見(jiàn)他們的 Reference,這里暫不做介紹

讓一個(gè) View 成為 Drop 目標(biāo)(Drop destination)

所有 UIView 或子類的對(duì)象都可以成為 Drop 目標(biāo),你需要執(zhí)行這三個(gè)步驟:
1.創(chuàng)建一個(gè) UIDropInteraction 對(duì)象
2.指定 drop interaction 的代理,所需要的協(xié)議是 UIDropInteractionDelegate
3.把 drop interaction 對(duì)象添加給 Drop destination 的 interactions 屬性

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

/// 把這個(gè)方法放在視圖控制器中方便調(diào)用
/// 這里的 view 指你自己創(chuàng)建的 drop destination
func customEnableDropping(on view: UIView, dropInteractionDelegate: UIDropInteractionDelegate) {
    let dropInteraction = UIDropInteraction(delegate: dropInteractionDelegate)
    view.addInteraction(dropInteraction)
}

告訴系統(tǒng)和用戶,拖拽的物體能否支持 Drop

當(dāng)用戶把某一個(gè)物體拖拽到 Destination App 的 destination view 里而并未放開手指時(shí),系統(tǒng)會(huì)調(diào)用 dropInteraction(_:canHandle:) 代理方法,這個(gè)方法有一個(gè) Bool 類型的返回值,用來(lái)告訴系統(tǒng)這個(gè)物體能否支持你的 App,如果支持,在 UI 上會(huì)顯示一個(gè)原諒色的 + 號(hào)提醒用戶可以在這里 let them go。

func dropInteraction(_ interaction: UIDropInteraction, canHandle session: UIDropSession) -> Bool {
    // 用來(lái)確定傳入的物體是否是 UIImage 對(duì)象
    return session.canLoadObjects(ofClass: [UIImage.self])
}

提供一個(gè)必須的 Drop 建議(Proposal)

為了從一個(gè) Session 中接受數(shù)據(jù),你必須實(shí)現(xiàn) dropInteraction(_:sessionDidUpdate) 的協(xié)議方法。

func dropInteraction(_ interaction: UIDropInteraction, sessionDidUpdate session: UIDropSession) -> UIDropProposal {
        // 讓系統(tǒng)“拷貝”這個(gè)項(xiàng)目
        return UIDropProposal(operation: .copy)
}

當(dāng)用戶成功 Drop 后,把 Drop 的 Items 提取出來(lái)

func dropInteraction(_ interaction: UIDropInteraction, performDrop session: UIDropSession) {
    // 讀取 items 數(shù)組并處理它們
    session.loadObjects(ofClass: UIImage.self) { imageItems in
        let images = imageItems as! [UIImage]
        self.imageView.image = images.first
    }
}

現(xiàn)在,你應(yīng)該擁有一個(gè)可以獲取來(lái)自其他地方的照片的 App 了,而且是通過(guò)拖拽的方式!

最後で

接下來(lái)會(huì)慢慢更新 Drag and Drop 特性其他的部分,例如讓你的 App 元素變得可以 Drag,而且還能夠拖拽到別的地方,甚至另一個(gè) App

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容