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:
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:
If I multiple items from another app it works fine, for example dragging multiple messages out of 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
}
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
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!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With