【概要】
ドラッグはUIエレメントに対するロングプレスをトリガーとして開始され、プレヴューイメージが表示され、drag session (UIDragSession)が開始される。drag sessionはドラッグ動作が完了もしくはキャンセルされるまで維持される。
プレヴューイメージはDestinationまでドラッグされる。Destinationがドラッグされたアイテムの型を扱える場合はその旨の表示がなされる。
ViewControllerにはdrag delegateやdrop delegateがアサインされる。
ViewController内のドラッグされる個別のviewはinteraction objectsを持つ必要がある。drag source(ドラッグ元)のviewはUIDragInteractionを、drag destination(ドラッグ先)のviewはUIDropInteractionを持つ。これらのInteractionには幅広いレンジのdelegateメソッドがあり、実装に応じてドラッグ・ドロップ・ライフサイクル内の様々な時点で呼ばれる。
各ドラッグ動作はdrag item (UIDragItem)で表される。drag itemはプレヴューイメージやitem provider (UIItemProvider)を持つ。item providerは移動対象のアイテムに関する情報を持ち、それはドロップが実施される場合の非同期トランスファーに使用される。
以下はdrag sourceとdrag destinationの最小コード
import UIKit
class ViewController: UIViewController {
var stringArray: [String] = [] {
didSet {
print(stringArray)
}
}
lazy var dragSource: UIView = {
let view = UIView()
let dragInteraction = UIDragInteraction(delegate: self)
view.addInteraction(dragInteraction)
return view
}()
lazy var dragDestination: UIView = {
let view = UIView()
let dropInteraction = UIDropInteraction(delegate: self)
view.addInteraction(dropInteraction)
return view
}()
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .white
view.addSubview(dragSource)
view.addSubview(dragDestination)
}
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
layout()
}
func layout() {
// dragSource
let itemSize: CGFloat = 100
dragSource.frame = CGRect(x: view.bounds.width/2 - itemSize/2, y: view.bounds.height/2 - itemSize/2, width: itemSize, height: itemSize)
dragSource.backgroundColor = .red
// dragDestination
dragDestination.frame = CGRect(x: view.bounds.width/2 - itemSize/2, y: view.bounds.height - itemSize/2 - 200, width: itemSize, height: itemSize)
dragDestination.backgroundColor = .blue
}
}
extension ViewController: UIDragInteractionDelegate {
func dragInteraction(_ interaction: UIDragInteraction, itemsForBeginning session: UIDragSession) -> [UIDragItem] {
let localObject = CustomClass(name: "me")
let stringItemProvider = NSItemProvider(object: "Hello" as NSString)
let item = UIDragItem(itemProvider: stringItemProvider)
item.localObject = localObject
return [
item
]
}
}
extension ViewController: UIDropInteractionDelegate {
func dropInteraction(_ interaction: UIDropInteraction, canHandle session: UIDropSession) -> Bool {
return true
}
func dropInteraction(_ interaction: UIDropInteraction, sessionDidEnd session: UIDropSession) {
let dropLocation = session.location(in: view)
}
}
class CustomClass {
var name: String
init(name: String) {
self.name = name
}
}