iOS开发:Compositional Layout设置分区Header失败,报视图出列错误
解决Compositional Layout中UICollectionView Header无法加载的错误
错误提示could not dequeue a view of kind: header with identifier headerReuseIdentifier的核心原因是布局中声明的Header元素类型与注册时的类型不匹配。
问题代码分析
- 注册Header时,你使用了系统标准的Header类型常量:
UICollectionView.elementKindSectionHeader - 但在
createLayout方法创建NSCollectionLayoutBoundarySupplementaryItem时,错误地将elementKind设为了自定义字符串"header",导致系统无法匹配到已注册的视图。
修复步骤
- 将布局中Header元素的
elementKind替换为系统常量UICollectionView.elementKindSectionHeader,确保与注册时的类型一致。 - 建议将复用标识符定义为常量,减少拼写错误的概率(可选但推荐)。
- 补充数据源必要方法的实现,保证CollectionView能正常加载内容。
修改后的完整代码
import UIKit class ViewController: UIViewController { // 定义复用标识符常量,避免拼写错误 private let cellReuseID = "cell" private let headerReuseID = "headerReuseIdentifier" private let collectionView: UICollectionView = { let view = UICollectionView(frame: .zero, collectionViewLayout: ViewController.createLayout()) view.register(UICollectionViewCell.self, forCellWithReuseIdentifier: ViewController().cellReuseID) view.register(UICollectionReusableView.self, forSupplementaryViewOfKind: UICollectionView.elementKindSectionHeader, withReuseIdentifier: ViewController().headerReuseID) 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)) // 替换为系统标准的Header类型常量 let headerElement = NSCollectionLayoutBoundarySupplementaryItem(layoutSize: headerSize, elementKind: UICollectionView.elementKindSectionHeader, alignment: .top) section.boundarySupplementaryItems = [headerElement] let layout = UICollectionViewCompositionalLayout(section: section) return layout } } extension ViewController: UICollectionViewDataSource, UICollectionViewDelegate { func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { return 4 } func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellReuseID, for: indexPath) cell.backgroundColor = .systemBlue return cell } func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView { let headerView = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: headerReuseID, for: indexPath) headerView.backgroundColor = .systemGray return headerView } }
内容的提问来源于stack exchange,提问作者Shivacharan Reddy
相关产品推荐
相关产品推荐

