0

I'm learning compositional layouts and I'm unable to set the header for a section, this is my entire code


import UIKit

class ViewController: UIViewController {
    
    private let collectionView: UICollectionView = {
                
        let view = UICollectionView(frame: .zero, collectionViewLayout: ViewController.createLayout())
        view.register(UICollectionViewCell.self, forCellWithReuseIdentifier: "cell")
        view.register(UICollectionReusableView.self, forSupplementaryViewOfKind: UICollectionView.elementKindSectionHeader, withReuseIdentifier: "headerReuseIdentifier")
        return view
    }()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        view.addSubview(collectionView)
        collectionView.dataSource = self
        collectionView.delegate = self
        
    }
    
    override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()
        
        collectionView.frame = view.bounds
    }
    
    static func createLayout() -> UICollectionViewCompositionalLayout {
        
        let itemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(0.5),
                                              heightDimension: .fractionalHeight(1.0))
        let item = NSCollectionLayoutItem(layoutSize: itemSize)
        
        let groupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0),
                                               heightDimension: .fractionalWidth(0.5))
        let group = NSCollectionLayoutGroup.horizontal(layoutSize: groupSize, subitems: [item])
        
        let section = NSCollectionLayoutSection(group: group)
        let headerSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: .absolute(44))
        let headerElement = NSCollectionLayoutBoundarySupplementaryItem(layoutSize: headerSize, elementKind: "header", alignment: .top)
        section.boundarySupplementaryItems = [headerElement]
        
        let layout = UICollectionViewCompositionalLayout(section: section)
        return layout
    }
}

extension ViewController: UICollectionViewDataSource, UICollectionViewDelegate {
    
    func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
        let headerView = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: "headerReuseIdentifier", for: indexPath)
        
        return headerView
        
    }
}


I have registered for header at the time of declaring collectionView, I have implemented all the protocols neededs as far as I'm aware.

  • You have registered a view for a `sectionHeader` but not for `header`. The error message says that it can't dequeue a view for `header`; either register a view for that kind or check `kind` in your function and return `nil` if `kind` isn't `.sectionHeader` – Paulw11 Aug 27 '23 at 20:19

1 Answers1

-1

In your code, you've specified "header" as the elementKind when creating the NSCollectionLayoutBoundarySupplementaryItem, but in your collectionView(_:viewForSupplementaryElementOfKind:at:) method, you're using "headerReuseIdentifier" as the kind parameter. These two values should match.

let headerElement = NSCollectionLayoutBoundarySupplementaryItem(layoutSize: headerSize, elementKind: UICollectionView.elementKindSectionHeader, alignment: .top)
section.boundarySupplementaryItems = [headerElement]

with the above it should work