I have a UICollectionView that has section headers, but not section footers. As such, I don't have a defined footer view.
Apple's documentation states that You must not return nil from this method.
func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
switch kind {
case UICollectionElementKindSectionHeader:
let headerView = collectionView.dequeueReusableSupplementaryView(ofKind: kind,
withReuseIdentifier: "MyHeaderView",
for: indexPath) as! MyHeaderView
switch indexPath.section
{
case 0:
headerView.label_title.text = "SOME HEADER"
case 1:
headerView.label_title.text = "ANOTHER HEADER"
default:
headerView.label_title.text = "UNKNOWN HEADER"
}
return headerView
default:
assert(false, "Unexpected element kind") // Not a good idea either
}
return nil // NOPE, not allowed
}
None of the above worked for me. In my case I have two UICollectionView
objects in the same view controller. First is horizontal, selecting an item of which displays the below UICollectionView
that is vertical and contains section headers.
From Apple docs:
This method must always return a valid view object. If you do not want a supplementary view in a particular case, your layout object should not create the attributes for that view. Alternatively, you can hide views by setting the isHidden property of the corresponding attributes to true or set the alpha property of the attributes to 0. To hide header and footer views in a flow layout, you can also set the width and height of those views to 0.
so dequeue the headerView
as usual because if you don't and just return an instance of UICollectionReusableView()
Xcode will complain the header view is not dequeued. And then if you don't want to display it for some reason (for me until user selects an item from the upper horizontal collection view) - set the width and height of the headerView
to 0.0
and return it.
let headerView = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: collectionHeaderReuseIdentifier, for: indexPath)
if objects.isEmpty {
headerView.frame.size.height = 0.0
headerView.frame.size.width = 0.0
return headerView
}
// Configure the header view here if needed
return headerView
For me personally, if you didn't tell UICollectionView to display section footers then it's not gonna show them. So it's OK to put preconditionFailure
in that delegate method.
My thought behinds that is that, UICollectionView won't gonna do things more that you tell it to do. So if you didn't tell UICollectionView to display section footers then it will not show them and it will be safe to have preconditionFailure
for those footer views case. But if you find a crash in that case then it's either UIKit bug which you should file a radar for that to tell Apple or it's your bug to ask UICollectionView to display section footer unintentionally.
So my code would look similar to this
func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
switch kind {
case UICollectionElementKindSectionHeader:
let headerView = collectionView.dequeueReusableSupplementaryView(ofKind: kind,
withReuseIdentifier: "MyHeaderView",
for: indexPath) as! MyHeaderView
/* Configure your section header here */
return headerView
default:
preconditionFailure("Invalid supplementary view type for this collection view")
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With