Reputation: 311
What are the ways in which a UICollectionViewDiffableDataSource
header can be reloaded?
I have a collection view with a header that displays user details, and rows that display posts, the model is
struct PostUser {
var user: User
var post: Post
}
when I change a property via the snapshot
var postUsers = [PostUser]() {
didSet {
self.applySnapshot(postUsers)
}
}
fileprivate func applySnapshot(_ postsUser: [PostUser]) {
var snapshot = NSDiffableDataSourceSnapshot<Section, PostUser>()
snapshot.appendSections([.main])
snapshot.appendItems(postsUser)
self.datasource.apply(snapshot, animatingDifferences: true)
}
the rows reload, however the supplementary header does not. The only way I can get the header to change is if I make the Section part of the model, so:
struct Section: Hashable {
var User: User
}
my apply snapshot now becomes
fileprivate func applySnapshot(_ postsUser: [PostUser]) {
var snapshot = NSDiffableDataSourceSnapshot<Section, PostUser>()
snapshot.appendSections([Section(User: self.user)])
snapshot.appendItems(postsUser)
self.datasource.apply(snapshot, animatingDifferences: true)
}
I then set the user separately
var user: User! = nil {
didSet {
self.applySnapshot(self.postUsers)
}
}
and the header reloads.
I don't quite understand why when I change something in postUsers, the rows reload, but the header does not - until I implement a model as part of the section?
I do understand that diffable works on hashing, and so when I change a property, the table reloads, but it feels like the header should also reload, but it is treated separately?
Upvotes: 5
Views: 3433
Reputation: 600
I figure out to use reloadSections
for iOS 15 previous is workable.
private func applyNewSnapshot() {
var newSnapshot = self.dataSource.snapshot()
if #available(iOS 15.0, *) {
self.dataSource.applySnapshotUsingReloadData(newSnapshot)
} else {
// Fallback on earlier versions
newSnapshot.reloadSections([.main])
self.dataSource.apply(newSnapshot, animatingDifferences: false)
}
}
Upvotes: 2
Reputation: 438
Headers are only reloaded when a change in the section itself is detected. If only the items change, the supplementary views will remain unchanged. Another thing you could look into depending on your case would be to set animatingDifferences
to false
when you want to reload a header since, as of the latest iOS 14 beta, that will trigger reloadData
. No diffing will be done.
Upvotes: 5