ios - 使用 tableView.reloadSections([0], with : UITableView. RowAnimation.right) 时从未调用 UITableView drop 方法

标签 ios swift uitableview drag-and-drop

我正在尝试在我的 UITableView 中实现拖放。拖动部分正在工作 - 我可以将应用程序外部拖动到提醒应用程序中,并查看 NSItemProvider 中包含的字符串。尽管实现了 UITableViewDropDelegate 方法并将 self 添加为 viewDidLoad 中的 dropDelegate 对象,但 PerformDropWith 方法永远不会被调用(无论是在模拟器中还是在真实设备上)。

我已在应用程序的另一个 UITableView 中成功实现了拖放功能。该表与该表的唯一区别是在 ViewController 容器内,因此我可以实现自己的 splitview,但据我所知,这应该没有任何区别。我已经阅读了网上的所有教程,但我看不出我错过了什么。我已将代码精简到最低限度,但它不起作用。

我有一个 tableView 的 @IBOutlet,并且工作正常,因为 ViewController 类中的许多其他东西都使用它。我在 Xcode 10.1 中使用 Swift 4.2。

类声明:

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() 放入这样的动画 block 中,它仍然有效:

UIView.transition(with: tableView,
                  duration: 0.5,
                  options: .transitionCrossDissolve,
                  animations: { self.tableView.reloadData() })

有谁知道为什么使用 tableView.reloadSections(_:with:) 不允许拖放的 Drop 一半工作? (我的表只有 1 个部分)

最佳答案

根据苹果文档:

The .move operation is available only for dragging within a single app.

func tableView(_ tableView: UITableView, dropSessionDidUpdate session: UIDropSession, withDestinationIndexPath destinationIndexPath: IndexPath?) -> UITableViewDropProposal {
    print("Can I drop") // NEVER PRINTS
    return UITableViewDropProposal(**operation: .move**, intent: .insertAtDestinationIndexPath)
}

尝试.copy

关于ios - 使用 tableView.reloadSections([0], with : UITableView. RowAnimation.right) 时从未调用 UITableView drop 方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55994837/

相关文章:

ios - Alamofire - 多部分表单数据 key :value

ios - 使用自动布局将 UIButtons 设置为等距离

swift - 快速更改默认的全局色调颜色

ios - swift : Disable FrontViewController when Rear is Displayed

iphone - UITableViewCell 显示索引路径行乱序

ios - 使用相同的自定义单元格实现两个 UITableViews 以供重用

ios - 在 Swift 中更改滑动删除背景的颜色

ios - 导航栏和状态栏的不同颜色

ios - 某些字体不适用于 XCode 中的 UIButton

ios - AutoLayout: subview 越过父 View 的边界