Методы удаления UITableView, которые никогда не вызывались при использовании tableView.reloadSections ([0], с: UITableView.RowAnimation.right) - PullRequest
0 голосов
/ 05 мая 2019

Я пытаюсь реализовать перетаскивание в моем 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 раздел)

Ответы [ 2 ]

0 голосов
/ 06 мая 2019

Чтобы это исправить, я добавил вызов tableView.reloadData() в самом конце viewDidLoad().Это позволило мне продолжать звонить tableView.reloadSections([0], with: UITableView.RowAnimation.right), когда я менял данные и хотел их оживить.

0 голосов
/ 05 мая 2019

Согласно Apple Docs:

Операция .move доступна только для перетаскивания в одном приложении.

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

Попробуйте .copy

...