I'm using the new drag and drop APIs on iOS 11 to reorder cells in a tableview inside the same app.
Here's my implementation for UITableViewDragDelegate
and UITableViewDropDelegate
:
extension TasksViewController: UITableViewDragDelegate {
func tableView(_ tableView: UITableView, itemsForBeginning session: UIDragSession, at indexPath: IndexPath) -> [UIDragItem] {
let string = tasks[indexPath.row]
guard let data = string.data(using: .utf8) else { return [] }
let itemProvider = NSItemProvider(item: data as NSData, typeIdentifier: kUTTypePlainText as String)
let item = UIDragItem(itemProvider: itemProvider)
item.localObject = string
return [item]
}
}
extension TasksViewController: UITableViewDropDelegate {
func tableView(_ tableView: UITableView, canHandle session: UIDropSession) -> Bool {
return true
}
func tableView(_ tableView: UITableView, dropSessionDidUpdate session: UIDropSession, withDestinationIndexPath destinationIndexPath: IndexPath?) -> UITableViewDropProposal {
if session.localDragSession != nil { // Drag originated from the same app.
return UITableViewDropProposal(operation: .move, intent: .insertAtDestinationIndexPath)
}
return UITableViewDropProposal(operation: .cancel, intent: .unspecified)
}
func tableView(_ tableView: UITableView, performDropWith coordinator: UITableViewDropCoordinator) {
guard let destinationIndexPath = coordinator.destinationIndexPath,
let dragItem = coordinator.items.first?.dragItem,
let task = dragItem.localObject as? String,
let sourceIndexPath = coordinator.items.first?.sourceIndexPath else {
return
}
tableView.performBatchUpdates({
self.tasks.remove(at: sourceIndexPath.row)
self.tasks.insert(task, at: destinationIndexPath.row)
tableView.deleteRows(at: [sourceIndexPath], with: .none)
tableView.insertRows(at: [destinationIndexPath], with: .none)
})
coordinator.drop(dragItem, toRowAt: destinationIndexPath)
}
}
This works fine, but has a weird glitch. When the last cell is being dragged, as soon as it's dropped, it appears at the bottom of the tableview for a split second then disappears.
What am I missing here?
Just change table deletion animation to .automatic, like so:
tableView.deleteRows(at: [sourceIndexPath], with: .automatic)
After that there won't be that weird animation.
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