I'm struggling to understand how to use UICollectionViewDiffableDataSource
and NSDiffableDataSourceSnapshot
to model change of items.
Let's say I have a simple item which looks like this:
struct Item {
var id: Int
var name: String
}
Based on the names of the generic parameters, UICollectionViewDiffableDataSource
and NSDiffableDataSourceSnapshot
should operate not with Item
itself, but only with identifier, which Int
in this example.
On the other hand, again based on names of generic parameters, UICollectionView.CellRegistration
should operate on complete Item
's. So my guess is that UICollectionViewDiffableDataSource.CellProvider
is responsible for finding complete Item's
by id. Which is unfortunate, because then aside from snapshots, I need to maintain a separate storage of items. And there is a risk that this storage may go out of sync with snapshots.
But it is still not clear to me how do I inform UICollectionViewDiffableDataSource
that some item changed its name
without changing its id
. I want UICollectionView
to update the relevant cell and animate change in content size, but I don't want insertion or removal animation.
There are two approaches that would work solve your problem in this scenario.
The first is to conform your
Item
model to the hashable protocol. This would allow you to use the entire model as anidentifier
, and the cell provider closure would pass you an object of typeItem
.UICollectionViewDiffableDataSource
would use the hash value for each instance of your model (which would consider both theid
andname
properties, thereby solving your name changing issue) to identify the data for a cell. This is better than trying to trick the collection view data source into considering only theid
as the identifier because, as you stated, other aspects of the model might change. The whole point of structs is to act as a value-type, where the composition of all the model's properties determine its 'value'...no need to trick the collection view data source into looking only atItem.id
.Do as you said, and create a separate dictionary in which you can retrieve the
Item
s based on their id's. While it is slightly more work to maintain a dictionary, it is a fairly trivial difference in terms of lines of code. All you should do is dump and recalculate the dictionary every time you apply a new snapshot. In this case, to update a cell when the model changes, make sure to swap out the model in your dictionary and callreloadItem
on your snapshot.While the second option is generally my preferred choice because the point of diffable data source is to allow for the handling of massive data sets by only concerning the data source with a simple identifier for each item, in this case your model is so simple that there's really no concern about wasted compute time calculating hash values, etc. If you think your model is likely to grow over time, I would probably go with the dictionary approach.