I'm converting my collection view to new iOS13 UICollectionViewDiffableDataSource... so I need to update cell information on demand.
Here is my code:
let snap = self.diffDataSouce.snapshot
snap?.reloadItems(withIdentifiers: [itemToUpdate]) //reload cell info
self.diffDataSouce.apply(snap, animatingDifferences: true)
But I get Invalid parameter not satisfying: indexPath || ignoreInvalidItems
...why?
My current snap
contains itemToUpdate
and also my array of models...
I think it's because snap.indexOfItemIdentifier(itemToUpdate)
returns not found (NSNotFound)...but that's should be impossible according data model.
Have you some hints?
Your data model has to conform to Hashable
and Equatable
, so that the diffing algorithm can track changes between snapshots.
If there is an issue with a collision between two objects, or you have implemented either of those protocols in such a way as to allow for two objects to appear equal to the diffing algorithm, you will get a runtime assert exception.
I'd track down exactly how your model object have inherited or implemented those protocols.
Have you implemented the static func ==
for your model? I had a similar issue using structs where equality is evaluated among all properties
For my case, reloading a hashable item was the problem. Instead I should have deleted hashable item and inserted anew. Following are the specifics.
My diffable ItemIdentifierType
was of AnyHashable type as in:
var dataSource: UICollectionViewDiffableDataSource<AHashableEnum, AnyHashable>!
And whenever I wanted to reload a single item like the author of this exchange, I was experiencing the crash:
var currentSnapshot = dataSource.snapshot()
currentSnapshot.reloadItems([hashableItemThatGotUpdated])
dataSource.apply(currentSnapshot, animatingDifferences: true)
I realized that since ItemIdentifierType is of AnyHashable type, reloading an item is not permitted if its hashvalue has changed. Because the hash value of the new item does not exist in the current snapshot and therefore is not reloadable. Instead I should have deleted the old item from the current snapshot and inserted the new Hashable identifer instead:
var currentSnapshot = dataSource.snapshot()
currentSnapshot.insertItems(identifiers: [NewHashableItemIdentifier], beforeItem: OldHashableItemIdentifier)
currentSnapshot.deleteItems(identifiers: [OldHashableItemIdentifier])
dataSource.apply(currentSnapshot, animatingDifferences: true)
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