Я пытаюсь реализовать перетаскивание в моем UITableView
. Часть перетаскивания работает - и я могу перетащить за пределы своего приложения в приложение напоминаний и увидеть строку, включенную в NSItemProvider
. Несмотря на реализацию методов UITableViewDropDelegate
и добавление self в качестве объекта dropDelegate в viewDidLoad, метод executeDropWith никогда не вызывается (ни в симуляторе, ни на реальном устройстве).
Я успешно реализовал Drag and Drop в другом UITableView
в своем приложении. Единственное различие между тем, где находится эта таблица, и тем, что эта таблица, находится внутри контейнера ViewController, поэтому я могу реализовать свой собственный splitview, но, насколько я знаю, это не должно иметь никакого значения. Я прочитал все уроки в сети об этом, и я не вижу, что мне не хватает. Я сократил свой код до минимума, и он не работает.
У меня есть @IBOutlet to tableView, и он работает нормально, потому что многие другие вещи в классе ViewController используют его. Я использую Swift 4.2 в Xcode 10.1.
Объявление класса:
class FolderMasterViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, UITableViewDropDelegate, UITableViewDragDelegate {
изнутри viewDidLoad:
self.tableView.dropDelegate = self
self.tableView.dragDelegate = self
self.tableView.dragInteractionEnabled = true
Соответствующие методы перетаскивания внутри класса:
func tableView(_ tableView: UITableView, itemsForBeginning session: UIDragSession, at indexPath: IndexPath) -> [UIDragItem] {
if let folder = folders?[indexPath.row] {
Logger.log("DRAGGING FOLDER with name: \(folder.name)")
let itemProvider = createItemProviderToDrag(with: folder.folderID)
let dragItem = UIDragItem(itemProvider: itemProvider)
// This stores the local object so we don't have to re-fetch it.
dragItem.localObject = folder
return [dragItem]
}
// we shouldn't ever get here; but returning an empty array means nothing should be dragged
return []
}
private func createItemProviderToDrag(with itemID: String) -> NSItemProvider {
let itemProvider = NSItemProvider()
itemProvider.registerDataRepresentation(forTypeIdentifier: kUTTypePlainText as String, visibility: .all) { completion in
let data = itemID.data(using: .utf8)
completion(data, nil)
return nil
}
return itemProvider
}
func tableView(_ tableView: UITableView, canHandle session: UIDropSession) -> Bool {
// NOTE: This returns true
print("Can I handle it? \(session.canLoadObjects(ofClass: NSString.self))")
return session.canLoadObjects(ofClass: NSString.self)
}
func tableView(_ tableView: UITableView, dropSessionDidUpdate session: UIDropSession, withDestinationIndexPath destinationIndexPath: IndexPath?) -> UITableViewDropProposal {
print("Can I drop") // NEVER PRINTS
return UITableViewDropProposal(operation: .move, intent: .insertAtDestinationIndexPath)
}
func tableView(_ tableView: UITableView, performDropWith coordinator: UITableViewDropCoordinator) {
print("PERFORM DROP") // NEVER PRINTS
}
вот что я вижу в выводе журнала:
05-May-2019 11:11:49:049 [FolderMasterViewController.swift:204] tableView(_:itemsForBeginning:at:) -> DRAGGING FOLDER with name: folder2
Can I handle it? true
2019-05-05 11:11:50.633390-0700 CWP[34092:10212965] PBItemCollectionServicer connection disconnected.
Я не верю, что сообщение PBItemCollectionServicer связано - я вижу сообщения в журнале другой таблицы, в которой я успешно реализовал перетаскивание, а другие сообщения stackoverflow говорят, что вы можете в значительной степени их игнорировать.
Дальнейшее копание и начало с очень пустого tableView и статического источника данных и добавление функциональности по крупицам - я обнаружил, что способ, которым я перезагружаю tableView, вызывает этот разрыв в функциональности перетаскивания.
Когда я менял список отображаемых папок, я использовал это:
tableView.reloadSections([0], with: UITableView.RowAnimation.right)
когда я изменяю это на
tableView.reloadData()
внезапное сбрасывание элементов в таблице снова работает, и я вижу отпечатки с tableView(_:performDropWith:)
. Даже если поместить tableView.reloadData () в анимированный блок, как это, он все равно работает:
UIView.transition(with: tableView,
duration: 0.5,
options: .transitionCrossDissolve,
animations: { self.tableView.reloadData() })
Кто-нибудь знает, почему использование tableView.reloadSections(_:with:)
не позволяет работать половине перетаскивания Drag & Drop? (В моей таблице только 1 раздел)