Alexander Ershov
Alexander Ershov

Reputation: 1157

Drag and drop works for UITableView without UITableViewDropDelegate

According to the Apple documentation to support drag and drop for UITableView I have to implement UITableViewDragDelegate and UITableViewDropDelegate. I implemented only UITableViewDragDelegate with fake implementation for tableView(_:itemsForBeginning:at:) (it return empty list). But this solution works.

Why does it work?

    import UIKit

    class TableViewController: UITableViewController, UITableViewDragDelegate {
        var data = [1, 2, 3, 4, 5]

        // MARK: - Table view drag delegate
        func tableView(_ tableView: UITableView, itemsForBeginning session: UIDragSession, at indexPath: IndexPath) -> [UIDragItem] {
            // fake implementation with empty list
            return []
        }

        // MARK: - Table view data source
        override func numberOfSections(in tableView: UITableView) -> Int {
            return 1
        }

        override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
            return data.count
        }

        override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
            let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
            cell.textLabel?.text = "Cell \(data[indexPath.row])"
            return cell
        }

        override func tableView(_ tableView: UITableView, moveRowAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) {
            let tmp = data[sourceIndexPath.row]
            data.remove(at: sourceIndexPath.row)
            data.insert(tmp, at: destinationIndexPath.row)
        }

        // MARK: - View controller
        override func viewDidLoad() {
            super.viewDidLoad()
            self.tableView.dragInteractionEnabled = true
            self.tableView.dragDelegate = self
        }
    }

Example

Upvotes: 1

Views: 2982

Answers (1)

matt
matt

Reputation: 535201

It doesn't work. What you are seeing is not drag and drop.

You are seeing row rearrangment, using the "reorder control". This mechanism is very old; it existed for many years before drag and drop was created. That is the effect of your implementation of

override func tableView(_ tableView: UITableView, moveRowAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) {

It is a UITableViewDataSource method; it has nothing to do with drag and drop. See:

https://developer.apple.com/documentation/uikit/uitableviewdatasource/1614867-tableview

If you delete that method, the old row rearrangement mechanism will cease to operate, and now you'll be using drag and drop and your implementation of

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

will be meaningful.

Upvotes: 2

Related Questions