Reputation: 2919
When I call dataSource?.apply(snapshot, animatingDifferences: true)
, the related UICollectionView deselects all cells.
This is a problem when receiving new data in the background as, when this change is commited, the user sees its current selection disappear.
How to avoid deselection of all collection items when apply(snapshot: animatingDifferences)
is called ?
Upvotes: 1
Views: 379
Reputation: 2919
After some digging, I found the root of the problem, and it lies inside Apple's code. At a minimum, I'd call that an "undocumented feature", some might say it's a bug.
When a snapshot is applied, the behavior of the UICollectionViewDiffableDataSource
differs, whether the ItemIdentifierType
is a value-type or a reference-type.
Of course, your ItemIdentifierType
must conform to Hashable
, but when calling apply(snapshot, animatingDifferences: true)
:
ItemIdentifierType
is a value-type (struct), then, its ==
and hash
functions are called, in order to compare the items of the newly received snapshot to the items of the currently shown snapshot, which allows to find the diff, animate differenes, and keep the selection if any (which was the original problem I asked help for).ItemIdentifierType
is a reference-type (class), then, its ==
and hash
function are not called, which means that the items of the new snapshot and the currently shown snapshot are compare with bare reference equality (are pointers equal). As a consequence, if you have built your items "from scratch" with new instances having the same hash, then the comparison is always false, and you don't get the animations, and you loose the selection.One easy work-around in this situation is to encapsulate your reference-type into a struct, which will forward ==
and hash
to the class ones, and use this struct as the ItemIdentifierType
Upvotes: 1