I'm using UICollectionView's performBatchUpdates(_:completion:)
method. The problem is that sometimes my complex diff logic fails and returns an incorrect number of sections to insert. This causes a mismatch between the number of items I insert and the number reported from the data source. Whenever that happens, we get the following error:
Assertion failure in -[CollectionView _endItemAnimationsWithInvalidationContext:tentativelyForReordering:animator:]
Error when performing batch updates: Invalid update: invalid number of sections. The number of sections contained in the collection view after the update (25) must be equal to the number of sections contained in the collection view before the update (19), plus or minus the number of sections inserted or deleted (0 inserted, 0 deleted).
I realize that the correct solution is to fix my diffing logic such that there is no mis-match between the number of items returned and the number of insertions I call.
However, what I want to do is make it so that even if my logic fails in the future, rather than clashing the app, it will simply reload the collection view's data.
How can I do this in Swift?
NSExceptions cannot be caught in Swift by default, so create a bridge similar to this one, or this one.
Even if you catch the assertion failure, the user cannot interact with the collection view, so you'll need to recreate the collection view.
TryCatch.try({
collectionView.performBatchUpdates({
collectionView.insertItems(at: indexPaths)
collectionView.insertSections(sections)
}, completion: nil)
}, catch: { exception in
print("Error updating collection view: \(exception)")
collectionView.removeFromSuperview()
// recreate the collection view (make sure to set datasource and delegates)
collectionView = ...
collectionView.dataSource = ...
collectionView.delegate = ...
}, finally: nil)
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