Как предотвратить добавление данных в существующую ячейку при перетаскивании ячейки табличного представления? - PullRequest
0 голосов
/ 07 ноября 2019

Я перетаскиваю ячейку табличного представления. Но в верхней части ячейки отображается значок «плюс», и, если я уроню, текст добавляется. Как предотвратить этот значок плюса, добавить поведение и просто изменить порядок?

extension CheckListTableViewController: UITableViewDragDelegate {

    func tableView(_ tableView: UITableView, itemsForBeginning session: UIDragSession, at indexPath: IndexPath) -> [UIDragItem] {
        if let item = self.boardMan.getCheckListItem(indexPath: indexPath) {
            if let stringData = item.title.data(using: .utf8) {
                let itemProvider = NSItemProvider(item: stringData as NSData, typeIdentifier: kUTTypePlainText as String)
                let dragItem = UIDragItem(itemProvider: itemProvider)
                dragItem.localObject = (item, indexPath, tableView)
                return [dragItem]
            }
        }
        return []
    }
extension CheckListTableViewController: UITableViewDropDelegate {

    func tableView(_ tableView: UITableView, performDropWith coordinator: UITableViewDropCoordinator) {
        if coordinator.session.hasItemsConforming(toTypeIdentifiers: [kUTTypePlainText as String]) {
            coordinator.session.loadObjects(ofClass: NSString.self) { (items) in
                switch (coordinator.items.first?.sourceIndexPath, coordinator.destinationIndexPath) {
                case (.some(let sourceIndexPath), .some(let destinationIndexPath)):
                    Log.debug("src: \(sourceIndexPath) dest: \(destinationIndexPath)")
                    let updatedIndexPaths: [IndexPath]
                    if sourceIndexPath.row < destinationIndexPath.row {
                        updatedIndexPaths =  (sourceIndexPath.row...destinationIndexPath.row).map { IndexPath(row: $0, section: 0) }
                    } else if sourceIndexPath.row > destinationIndexPath.row {
                        updatedIndexPaths =  (destinationIndexPath.row...sourceIndexPath.row).map { IndexPath(row: $0, section: 0) }
                    } else {
                        updatedIndexPaths = []
                    }
                    if let checkListItem = self.utils.getCheckListItem(indexPath: sourceIndexPath) {
                        self.tableView.beginUpdates()
                        _ = self.utils.removeCheckListItem(indexPath: sourceIndexPath)
                        _ = self.utils.insertCheckListItem(checkListItem, indexPath: destinationIndexPath)
                        self.tableView.reloadRows(at: updatedIndexPaths, with: .none)
                        self.tableView.endUpdates()
                    }
                default:
                    Log.debug("default case")
                }
            }
        }
    }

    func tableView(_ tableView: UITableView, dropSessionDidUpdate session: UIDropSession, withDestinationIndexPath destinationIndexPath: IndexPath?) -> UITableViewDropProposal {
        if tableView.hasActiveDrag {
            return UITableViewDropProposal(operation: .move, intent: .insertAtDestinationIndexPath)
        }
        return UITableViewDropProposal(operation: .forbidden)
    }
}

В табличном представлении установлены делегаты перетаскивания и добавлены гостевые свайпы.

self.tableView.dragDelegate = self
self.tableView.dropDelegate = self
self.tableView.dragInteractionEnabled = true

Пожалуйста, смотрите скриншот ниже.

snap

1 Ответ

1 голос
/ 07 ноября 2019

Если вы хотите поддерживать перетаскивание только с целью переупорядочения строк, вам не нужен код, который вы опубликовали.

Реализуйте обычные методы переупорядочения UITableViewDataSource и UITableViewDelegate. ,Установите таблицы dragDelegate и dropDelegate. Вам нужно реализовать только один метод, каждый из UITableViewDragDelegate и UITableViewDropDelegate, и их реализации тривиальны.

Для простого односекционного табличного представления все, что вам нужно, это следующее:

override func tableView(_ tableView: UITableView, canMoveRowAt indexPath: IndexPath) -> Bool {
    return true
}

override func tableView(_ tableView: UITableView, moveRowAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) {
    // Update your data model array to move the item at sourceIndexPath.row to destinationIndexPath.row
}

// MARK: - UITableViewDragDelegate

func tableView(_ tableView: UITableView, itemsForBeginning session: UIDragSession, at indexPath: IndexPath) -> [UIDragItem] {
    return []
}

// MARK: - UITableViewDropDelegate

func tableView(_ tableView: UITableView, performDropWith coordinator: UITableViewDropCoordinator) {
    // no-op
}

Убедитесь, чтовы устанавливаете свойства dragDelegate и dropDelegate представления таблицы на self в viewDidLoad или в раскадровке. Вам также необходимо включить свойство dragInteractionEnabled.

override func viewDidLoad() {
    super.viewDidLoad()

    self.tableView.dragDelegate = self
    self.tableView.dropDelegate = self
    self.tableView.dragInteractionEnabled = true
}

Это все, что вам нужно для поддержки переупорядочения строк с помощью перетаскивания. Конечно, для сложных моделей данных и нескольких разделов вам может потребоваться также реализовать метод делегата targetIndexPathForMoveFromRowAt, а вашей логике в moveRowAt может потребоваться дополнительная логика.


Что интересно, так это необходимостьустановить dropDelegate и включить dragInteractionEnabled необходимо только для айфонов. Версия для iPad (и Mac Catalyst) не нуждается в этих наборах.

...