检测我当前正在将Table单元格拖到哪个视图控制器上



我长按TableViewController的单元格并在我的应用程序周围拖动单元格。我怎么能检测到我在同一应用程序中拖动另一个TableViewController ?如果我把单元格放到另一个TableViewController中,我能处理这个。但是,我如何检测到单元格从TableA已经进入并被拖到TableB周围,而不释放我的手指?

类似的问题似乎是关于检测与给定视图的子视图的碰撞,而不是另一个/不同的视图。示例:iOS -拖放碰撞检测如何检测当您选择的项目拖到另一个子视图?

您可以通过实现dropSessionDidEnter…你可能还想实现dropSessionDidExit

我们将从您已经在https://www.hackingwithswift.com/example-code/uikit/how-to-add-drag-and-drop-to-your-app学习的教程开始…(略有修改):

import MobileCoreServices
class DragDropViewController: UIViewController, UITableViewDataSource, UITableViewDelegate,
UITableViewDragDelegate, UITableViewDropDelegate {

var leftTableView = UITableView()
var rightTableView = UITableView()

var leftItems: [String] = []
var rightItems: [String] = []

override func viewDidLoad() {
super.viewDidLoad()

leftItems = (1...20).map { "Left Row ($0)" }
rightItems = (1...20).map { "Right Row ($0)" }
leftTableView.dataSource = self
rightTableView.dataSource = self

leftTableView.frame = CGRect(x: 0, y: 40, width: 150, height: 400)
rightTableView.frame = CGRect(x: 180, y: 40, width: 150, height: 400)

leftTableView.register(UITableViewCell.self, forCellReuseIdentifier: "Cell")
rightTableView.register(UITableViewCell.self, forCellReuseIdentifier: "Cell")

view.addSubview(leftTableView)
view.addSubview(rightTableView)

leftTableView.dragDelegate = self
leftTableView.dropDelegate = self
rightTableView.dragDelegate = self
rightTableView.dropDelegate = self

leftTableView.dragInteractionEnabled = true
rightTableView.dragInteractionEnabled = true
}

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if tableView == leftTableView {
return leftItems.count
} else {
return rightItems.count
}
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)

if tableView == leftTableView {
cell.textLabel?.text = leftItems[indexPath.row]
} else {
cell.textLabel?.text = rightItems[indexPath.row]
}

return cell
}

func tableView(_ tableView: UITableView, itemsForBeginning session: UIDragSession, at indexPath: IndexPath) -> [UIDragItem] {
let string = tableView == leftTableView ? leftItems[indexPath.row] : rightItems[indexPath.row]
guard let data = string.data(using: .utf8) else { return [] }
let itemProvider = NSItemProvider(item: data as NSData, typeIdentifier: kUTTypePlainText as String)

return [UIDragItem(itemProvider: itemProvider)]
}

func tableView(_ tableView: UITableView, performDropWith coordinator: UITableViewDropCoordinator) {
let destinationIndexPath: IndexPath

if let indexPath = coordinator.destinationIndexPath {
destinationIndexPath = indexPath
} else {
let section = tableView.numberOfSections - 1
let row = tableView.numberOfRows(inSection: section)
destinationIndexPath = IndexPath(row: row, section: section)
}

// attempt to load strings from the drop coordinator
coordinator.session.loadObjects(ofClass: NSString.self) { items in
// convert the item provider array to a string array or bail out
guard let strings = items as? [String] else { return }

// create an empty array to track rows we've copied
var indexPaths = [IndexPath]()

// loop over all the strings we received
for (index, string) in strings.enumerated() {
// create an index path for this new row, moving it down depending on how many we've already inserted
let indexPath = IndexPath(row: destinationIndexPath.row + index, section: destinationIndexPath.section)

// insert the copy into the correct array
if tableView == self.leftTableView {
self.leftItems.insert(string, at: indexPath.row)
} else {
self.rightItems.insert(string, at: indexPath.row)
}

// keep track of this new row
indexPaths.append(indexPath)
}

// insert them all into the table view at once
tableView.insertRows(at: indexPaths, with: .automatic)
}
}


func tableView(_ tableView: UITableView, dropSessionDidUpdate session: UIDropSession, withDestinationIndexPath destinationIndexPath: IndexPath?) -> UITableViewDropProposal {
var dropProposal = UITableViewDropProposal(operation: .cancel)

// Accept only one drag item.
guard session.items.count == 1 else { return dropProposal }

// The .move drag operation is available only for dragging within this app and while in edit mode.
if tableView.hasActiveDrag {
if tableView.isEditing {
dropProposal = UITableViewDropProposal(operation: .move, intent: .insertAtDestinationIndexPath)
}
} else {
// Drag is coming from outside the app.
dropProposal = UITableViewDropProposal(operation: .copy, intent: .insertAtDestinationIndexPath)
}

return dropProposal
}

}

如果你运行这个,你应该有"left"one_answers";right"表视图,并且您应该能够从左边的表中拖放到右边的表中。

如果您的目标是在拖动进入时执行某些操作右表,实现以下功能:

func tableView(_ tableView: UITableView, dropSessionDidEnter session: UIDropSession) {
if tableView == rightTableView {
tableView.layer.borderWidth = 2
}
}

func tableView(_ tableView: UITableView, dropSessionDidExit session: UIDropSession) {
tableView.layer.borderWidth = 0
}

func tableView(_ tableView: UITableView, dropSessionDidEnd session: UIDropSession) {
rightTableView.layer.borderWidth = 0
}

当dropsession进入右表视图时,我们将其边框宽度设置为2,当session退出右表视图时将其设置为0。

我们还实现了dropSessionDidEnd,所以我们可以在drop完成时将边界重置为0。我们可以在performDropWith这样做,但我这样做是为了清晰。

最新更新