Option
Quote from Apple Engineer
If you have mutable or complex data objects, you should not use them as item identifiers directly but rather just use your objects' identifiers with diffable data source and then fetch the correct object from your data store when configuring the cell by referencing the identifier. So in your gist for example, you should store the UUID identifier of your item in the data source instead of the whole object. This will work, but it requires more work and bookkeeping and is arguably less efficient.
2. Option
Adjust your identifier (model) such that hash and == changes whenever your displayed content changes
struct MyItem: Hashable {
let identifier = UUID()
var value: String?
func hash(into hasher: inout Hasher) {
hasher.combine(identifier)
hasher.combine(value)
}
static func == (lhs: MyItem, rhs: MyItem) -> Bool {
lhs.identifier == rhs.identifier && value == value
}
}
Many people recommended this approach, but it has the following caveat: when value changes, the model becomes a different identifier for the diffable data source and thus a simultaneous move of the item is decomposed into a delete + insert, which causes a visual bug, but nothing more.
3. Option - My Solution
Keep your model as is. First apply the snapshot as usual, then apply the snapshot with animatingDifferences: false in the completion handler.
dataSource.apply(snapshot, animatingDifferences: true, completion: {
dataSource.apply(snapshot, animatingDifferences: false)
})
The bug seems to be that on apply with animatingDifferences: true, diffable data source updates the configured cells before internally updating the identifiers that stayed "equal" according to ==. Note: In the completion handler one could also call collectionView.reloadData(), or anything else that forces the configured cells to be updated.
Post
Replies
Boosts
Views
Activity
Unfortunately I doubt SwiftUI’s performance would be possible if it was a “normal” framework that is independent of the OS. Also it probably relies on the specific UIKit version that ships with the OS release.
Still not fixed in final Xcode 11.4, this is definitely a bug, either in SPM or Xcode.