I have these items
I'm displaying these months in a collectionview and when tapping on one I set it's isSelected property to true and the cell should change the label's colour based on isSelected.
This is how I create a new snapshot:
When the user taps on a cell, this happens:
The UI doesn't change, unless I scroll up and down (dequeue the cell again) or I call the reloadItems function.
I explicitly tell the system that two months are not the same if one is selected and the other is not (and their name is the same), I expected that the UICollectionViewDiffableDataSource will use the hash and == functions to check which cells needs to be reloaded, however this clearly is not the case.
Although, when I replace the instance itself, it will reload the cell (same happens if I mutate structs instead of classes).
The hash/== functions:
This makes me think that the system compares the memory addresses and not the hash/equality of the items. Can you please confirm if this is the case.
Since I provide all the information needed to work out the difference between a new and an old snapshot I expected that the UICollectionViewDiffableDataSource is smarter and encapsulates this logic and I don't have to write the additions/deletions/reorders/replacements logic every single time I use this API.
Thanks a lot,
Bence
Code Block swift class Month: Hashable { let name: String var isSelected: Bool }
I'm displaying these months in a collectionview and when tapping on one I set it's isSelected property to true and the cell should change the label's colour based on isSelected.
This is how I create a new snapshot:
Code Block swift func makeSnapshot() -> NSDiffableDataSourceSnapshot<Section, Month> { var snapshot = NSDiffableDataSourceSnapshot<Section, Month>() snapshot.appendSections([Section.main]) snapshot.appendItems(months, toSection: .main) return snapshot }
When the user taps on a cell, this happens:
Code Block swift func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { let month = dataSource.itemIdentifier(for: indexPath) months.forEach({ $0.isSelected = false }) month?.isSelected = true dataSource.apply(makeSnapshot()) }
The UI doesn't change, unless I scroll up and down (dequeue the cell again) or I call the reloadItems function.
I explicitly tell the system that two months are not the same if one is selected and the other is not (and their name is the same), I expected that the UICollectionViewDiffableDataSource will use the hash and == functions to check which cells needs to be reloaded, however this clearly is not the case.
Although, when I replace the instance itself, it will reload the cell (same happens if I mutate structs instead of classes).
The hash/== functions:
Code Block swift extension Month { func hash(into hasher: inout Hasher) { hasher.combine(name) hasher.combine(isSelected) } static func == (lhs: DemoViewController.Month, rhs: DemoViewController.Month) -> Bool { lhs.name == rhs.name && lhs.isSelected == rhs.isSelected } }
This makes me think that the system compares the memory addresses and not the hash/equality of the items. Can you please confirm if this is the case.
Since I provide all the information needed to work out the difference between a new and an old snapshot I expected that the UICollectionViewDiffableDataSource is smarter and encapsulates this logic and I don't have to write the additions/deletions/reorders/replacements logic every single time I use this API.
Thanks a lot,
Bence