Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to use iOS 11 Drag and Drop to reorder multiple items/cells at a time in UITableView?

I know it's possible to reorder a single item/cell at a time when using the new UITableViewDropDelegate and UITableViewDragDelegate delegates but is it possible to support handling multiple.

For example in this screenshot I am holding a single item: Dragging a single item/cell

And dropping the cell puts it in to place.

However when I grab multiple cells I get the no entry sign and the cells wont reorder: Multiple selection Drag and Drop with no entry sign

If I multiple items from another app it works fine, for example dragging multiple messages out of iMessage: Multiple selection Drag and Drop from iMessage

Is it possible to do this when reordering a table view with only local items so that you can reorder quicker?

Here is my code:

UITableViewDragDelegate

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

    func tableView(_ tableView: UITableView, itemsForAddingTo session: UIDragSession, at indexPath: IndexPath, point: CGPoint) -> [UIDragItem] {
        return [getDragItem(forIndexPath: indexPath)]
    }

    func getDragItem(forIndexPath indexPath: IndexPath) -> UIDragItem {
        // gets the item
    }
}

UITableViewDropDelegate

extension DotViewController: UITableViewDropDelegate {
    func tableView(_ tableView: UITableView, canHandle session: UIDropSession) -> Bool {
        return true
    }

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

    func tableView(_ tableView: UITableView, performDropWith coordinator: UITableViewDropCoordinator) {
        // Handles Drop
    }
}

viewDidLoad

override func viewDidLoad() {
    super.viewDidLoad()

    tableView.dataSource = self
    tableView.delegate = self
    tableView.dragDelegate = self
    tableView.dropDelegate = self

    tableView.dragInteractionEnabled = true
}
like image 636
Radther Avatar asked Jul 18 '17 14:07

Radther


2 Answers

It's possible to do multi-row reordering yourself by providing references to all the selected cells via your drag delegate (e.g. an array of section.row's ) then implementing tableView:performDropWith:withCoordinator to reorder them. (I suspect you know this)

If you want to support reordering by returning a drop proposal of UITableViewDropProposal(operation: .move, intent: .insertAtDestinationIndexPath) so UIKit uses the pre-iOS 11 tableView:moveRowAt:to function then this only supports a single row.

Table view moveRowAt IndexPath to IndexPath. You can continue to implement this, if you like, to support reordering, using Drag and Drop. Because table view is actually going to call this instead of calling through perform drop with coordinator, if you've returned that magic drop proposal and a single row is actually being reordered.

Source: https://developer.apple.com/videos/play/wwdc2017/223/?time=1836

like image 130
Andrew Grant Avatar answered Nov 17 '22 23:11

Andrew Grant


I've tried the same with UICollectionView, then I found this:
link to tweet posted by Tyler Fox who was an active participant in the drag & drop development and you can also see him in the 2017-2018 WWDC videos related to the topic.

Tweet's content:

Table and collection view doesn’t support UI for multi-item reordering, it’s quite tricky to implement correctly.
You can use an intent of .unspecified and provide your own UI for it during the session though, and the drop will be accepted.
Please file an enhancement request if you'd like to see it supported with API. Any details on your specific use case are appreciated!

like image 26
user2569338 Avatar answered Nov 18 '22 01:11

user2569338