What to return from collectionView(_:viewForSupplementaryElementOfKind:at:) when you want to return nothing?

Viewed 11612

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
}
6 Answers

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
Related