I have a UICollectionViewDiffableDataSource
like so:
var data:UICollectionViewDiffableDataSource<Section, Message>!
I define my section header's layout like so:
let header = NSCollectionLayoutBoundarySupplementaryItem(
layoutSize: .init(widthDimension: .fractionalWidth(1.0), heightDimension: .estimated(10)),
elementKind: UICollectionView.elementKindSectionHeader,
alignment: .top
)
section.boundarySupplementaryItems = [header]
Lastly, to return my header, I have this function that returns the UICollectionReusableView
like so:
func setupHeaderData() {
data.supplementaryViewProvider = { collectionView, kind, indexPath in
return DateStampBuilder(data: self.data, style: self.style).build(collectionView: collectionView, kind: kind, indexPath: indexPath)
}
}
What's great: I can see my header's in my UICollectionView
.
What I want: How can I optionally decide not to show a specific header for a specific section?
When I try to return nil
in the following function:
data.supplementaryViewProvider = { collectionView, kind, indexPath in
I get the following error:
Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'the view returned from -collectionView:viewForSupplementaryElementOfKind:atIndexPath (UICollectionElementKindSectionHeader,<NSIndexPath: 0xb461f3e1dd0c21dc> {length = 2, path = 0 - 0}) was not retrieved by calling -dequeueReusableSupplementaryViewOfKind:withReuseIdentifier:forIndexPath: or is nil ((null))'
My only thoughts on how to "optionally" return a header for a section is to register another header view that has a height of zero and return this header when I don't want to return any header at all.
But to me, this seems like a bit of a messy approach, it would be much cleaner if I could just return nil
when I do not what to show the header.
What am I doing wrong?
Thanks for your help!
This should be done when creating the layout for the collectionView. Here's an example on how to do it using UICollectionLayoutListConfiguration
:
let sectionProvider = { [weak self] (sectionIndex: Int, layoutEnvironment: NSCollectionLayoutEnvironment) -> NSCollectionLayoutSection? in
var section: NSCollectionLayoutSection
var listConfiguration = UICollectionLayoutListConfiguration(appearance: .insetGrouped)
if condition {
listConfiguration.headerMode = .supplementary
} else {
listConfiguration.headerMode = .none
}
section = NSCollectionLayoutSection.list(using: listConfiguration, layoutEnvironment: layoutEnvironment)
return section
}
let layout = UICollectionViewCompositionalLayout(sectionProvider: sectionProvider)
collectionView.setCollectionViewLayout(layout, animated: true)
Your condition can obviously be bound to your dataSource and section indexes so you do not run out of sync with dynamically created sections.