I have a problem with applying NSDiffableDataSourceSnapshot
to UICollectionViewDiffableDataSource
. Imagine this situation: I have two items and I want to remove the second one and also I want to reload all other items in that section.
I do it like this:
var snapshot = oldSnapshot
if let item = getterForItemToDelete() {
snapshot.deleteItems([item])
}
snapshot.reloadItems(otherItems)
But then in cell provider of data source app crashes since it tries to get cell for item identifier for which I no longer have data so I have to return nil
:
let dataSource = MyDataSource(collectionView: collectionView) { [weak self] collectionView, indexPath, identifier in
guard let viewModel = self?.viewModel.item(for: identifier) else { return nil }
...
}
What is strange is that when I try to debug it and print my items when I apply snapshot, it prints one item:
(lldb) print snapshot.itemIdentifiers(inSection: .mySection)
([App.MyItemIdentifier]) $R0 = 1 value {
[0] = item (item = "id")
}
But, immediately after this, in cell provider I get that I have two items, which I don't
(lldb) print self?.dataSource.snapshot().itemIdentifiers(inSection: .mySection)
([App.MyItemIdentifier]) $R1 = 2 values {
[0] = item (item = "ckufpa58100041ps6gmiu5zl6")
[1] = item (item = "ckufpa58100051ps69yrgaspv")
}
What is even more strange is that this doesn't happen when I have 3 items and I want to delete one and reload the others.
One workaround which solves my problem is to return empty cell instead of nil
in cell provider:
let dataSource = MyDataSource(collectionView: collectionView) { [weak self] collectionView, indexPath, identifier in
guard let viewModel = self?.viewModel.item(for: identifier) else {
return collectionView.dequeueReusableCell(withReuseIdentifier: "UICollectionViewCell", for: indexPath)
}
...
}
And the last strange thing, when I do this and then I look to View Hierarchy debugger, there is just one cell, so it seems that the empty cell gets removed.
Does anybody know what could I do wrong or is this just expected behavior? Since I didn't find any mention of providing cells for some sort of optimalizations, animations or something in the documentation.