I have an array of sections which contains an array of items. It is what I am using to populate my collectionview using compositional layout. My layout could always change based on the user. They can delete, add or modify sections or items. The collectionview shows sectionheaders based on the number of sections in the array. The sectionheader is a boundarySupplementaryItem. I get this error when deleting a section or removing all from the array. "Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'request for layout attributes for supplementary view UICollectionElementKindSectionHeader in section 1 when there are only 0 sections in the collection view'.
if i comment out this code, it wont crash but the section header wont be there
let layoutSectionHeader = createSectionHeader()
layoutSection.boundarySupplementaryItems = [layoutSectionHeader]
This is the code to generate a compositional layout and what happens to the sections array on didSet.
func createCompositionalLayout(sections: [Section]) -> UICollectionViewLayout {
guard !sections.isEmpty else { return UICollectionViewLayout() }
let layout = UICollectionViewCompositionalLayout { [weak self]
sectionIndex, layoutEnvironment in
let section = sections[sectionIndex]
switch section.type {
case .mediumCell:
return self?.createMediumTableSection(using: section)
default:
return self?.createEmptySection(using: section)
}
}
let configuration = UICollectionViewCompositionalLayoutConfiguration()
configuration.interSectionSpacing = 15
layout.configuration = configuration
return layout
}
func createMediumTableSection(using section: Section) -> NSCollectionLayoutSection {
let itemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1), heightDimension: .fractionalHeight(0.33))
let layoutItem = NSCollectionLayoutItem(layoutSize: itemSize)
layoutItem.contentInsets = NSDirectionalEdgeInsets(top: 0, leading: 5, bottom: 0, trailing: 5)
let layoutGroupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(0.93), heightDimension: .fractionalWidth(0.55))
let layoutGroup = NSCollectionLayoutGroup.vertical(layoutSize: layoutGroupSize, subitems: [layoutItem])
let layoutSection = NSCollectionLayoutSection(group: layoutGroup)
layoutSection.orthogonalScrollingBehavior = .groupPagingCentered
layoutSection.interGroupSpacing = 20
layoutSection.contentInsets = NSDirectionalEdgeInsets(top: 0, leading: 20, bottom: 0, trailing: 0)
let layoutSectionHeader = createSectionHeader()
layoutSection.boundarySupplementaryItems = [layoutSectionHeader]
return layoutSection
}
func createSectionHeader() -> NSCollectionLayoutBoundarySupplementaryItem {
let layoutSectionHeaderSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(0.93), heightDimension: .estimated(80))
let layoutSectionHeader = NSCollectionLayoutBoundarySupplementaryItem(layoutSize: layoutSectionHeaderSize, elementKind: UICollectionView.elementKindSectionHeader, alignment: .top)
return layoutSectionHeader
}
func createEmptySection(using section: Section) -> NSCollectionLayoutSection {
let itemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1), heightDimension: .fractionalHeight(1))
let layoutItem = NSCollectionLayoutItem(layoutSize: itemSize)
layoutItem.contentInsets = NSDirectionalEdgeInsets(top: 0, leading: 5, bottom: 0, trailing: 5)
let layoutGroupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(0.93), heightDimension: .fractionalWidth(0.55))
let layoutGroup = NSCollectionLayoutGroup.vertical(layoutSize: layoutGroupSize, subitems: [layoutItem])
let layoutSection = NSCollectionLayoutSection(group: layoutGroup)
layoutSection.orthogonalScrollingBehavior = .groupPagingCentered
let layoutSectionHeader = createSectionHeader()
layoutSection.boundarySupplementaryItems = [layoutSectionHeader]
return layoutSection
}
var sections = [Section]() {
didSet {
DispatchQueue.main.async {
if self.sections.isEmpty {
self.mainView.collectionView.backgroundView = MainEmptyView()
self.addItemButton.isEnabled = false
self.editItemButton.isEnabled = false
} else {
self.mainView.collectionView.backgroundView = nil
}
self.mainView.collectionView.collectionViewLayout = self.createCompositionalLayout(sections: self.sections)
self.mainView.collectionView.reloadData()
}
}
}