SwiftReorder
SwiftReorder copied to clipboard
Reordering to top is broken on iOS 13.3, Xcode 11.3.1
So spend half a day today trying to figure out and maybe fix a bug with cell reordering when you try to reorder a cell to the top with a scrolling involved. Basically all you need to do is to scroll at least a little bit down and then try to reorder cell to the very top. There'll be an animation glitch on the last cell reordering. It especially obvious for grouped table views. I used iPhone SE for tests.
I tried to force layout first and contentOffset
restore after to prevent jumps but while I almost fixed a jump glitch cells content and sizes started to glitch so no idea how to fix this one.
Well at least found a workaround for now - just do not animate last cell move. In ReorderController+DestinationRow.swift
updateDestinationRow()
use this:
if #available(iOS 13.0, *), newContext.destinationRow == IndexPath(row: 0, section: 0) {
tableView.reloadData()
} else {
tableView.moveRow(at: context.destinationRow, to: newContext.destinationRow)
}
Not sure, though, about the concrete iOS 13 version this bug was introduced.
Reproduces on iOS 13.2.2 and iOS 13.3
I am running into this issue as well & added the fix you provided but it created a new issue where it makes all other cells I scroll over invisible. Do you know what might be causing that? Thank you
@dontKnowWhatIAmDoin try to replace original lines:
tableView.beginUpdates()
tableView.deleteRows(at: [context.destinationRow], with: .fade)
tableView.insertRows(at: [newContext.destinationRow], with: .fade)
tableView.endUpdates()
with those:
if #available(iOS 13.0, *), newContext.destinationRow == IndexPath(row: 0, section: 0) {
tableView.reloadData()
} else {
tableView.beginUpdates()
tableView.deleteRows(at: [context.destinationRow], with: .fade)
tableView.insertRows(at: [newContext.destinationRow], with: .fade)
tableView.endUpdates()
}
Overall, thise fix shouldn't affect anything except reordering to the first row.
Thank you, this worked for me.
@anton-plebanovich That works great, thanks :D
@anton-plebanovich , why not just tableView.moveRow(at: sourceIndexPath, to: destinationIndexPath)?
@andreigubceac I am not the author so can't be sure, just left that as is.
@anton-plebanovich It's not working anymore (iOS 13.6) even when using the fixes here. Does anyone have any updated workaround?
have the same issue , and this workaround does not fix the issue
have the same issue, is it fix?
Hi guys found an alternative. Check full answer here
tableView.dragInteractionEnabled = true
tableView.dragDelegate = self
tableView.dropDelegate = self
func tableView(_ tableView: UITableView, moveRowAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) { }
extension TableView: UITableViewDragDelegate {
func tableView(_ tableView: UITableView, itemsForBeginning session: UIDragSession, at indexPath: IndexPath) -> [UIDragItem] {
return [UIDragItem(itemProvider: NSItemProvider())]
}
}
extension TableView: UITableViewDropDelegate {
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) {
}
}