Home > front end >  How do I prevent my section headers from overlapping cells in a compositional layout
How do I prevent my section headers from overlapping cells in a compositional layout

Time:11-05

I want a header to appear above each section in my compositional layout, but I can't find a way to make them appear above the content rather than overlapping it, here is my layout code:

func createLayout() -> UICollectionViewLayout {
    
    let config = UICollectionViewCompositionalLayoutConfiguration()
    config.scrollDirection = .horizontal
    config.interSectionSpacing = 16
    
    let layout = UICollectionViewCompositionalLayout(sectionProvider: {
        
        (sectionIndex: Int, layoutEnvironment: NSCollectionLayoutEnvironment) -> NSCollectionLayoutSection? in
        
        let leadingItem = NSCollectionLayoutItem(
            layoutSize: NSCollectionLayoutSize(widthDimension: .fractionalWidth(1),
                                               heightDimension: .estimated(50)))
        
        let widthFraction: CGFloat = UIScreen.main.bounds.size.width > UIScreen.main.bounds.size.height ? 0.2 : 0.8
        let containerGroup = NSCollectionLayoutGroup.vertical(
            layoutSize: NSCollectionLayoutSize(widthDimension: .fractionalWidth(widthFraction),
                                               heightDimension: .estimated(50)),
            subitems: [leadingItem])
        
        let section = NSCollectionLayoutSection(group: containerGroup)
        section.boundarySupplementaryItems = [self.makeHeader()]
        section.orthogonalScrollingBehavior = .continuous
        section.interGroupSpacing = 16
        return section
        
    }, configuration: config)
    
    return layout
}

func makeHeader() -> NSCollectionLayoutBoundarySupplementaryItem {
    let widthFraction: CGFloat = UIScreen.main.bounds.size.width > UIScreen.main.bounds.size.height ? 0.2 : 0.8
    let size = NSCollectionLayoutSize(widthDimension: .fractionalWidth(widthFraction),
                                      heightDimension: .estimated(50))
    let sectionHeader = NSCollectionLayoutBoundarySupplementaryItem(layoutSize: size,
                                                                   elementKind: UICollectionView.elementKindSectionHeader,
                                                                    alignment: .top)
    return sectionHeader
}

and here is a screenshot of what is happening, I need the text that says "Column1" to appear above, not overlapping the column cells: enter image description here

CodePudding user response:

Here was my solution, but it only allows for fixed-height headers on my sections:

you need to set

section.supplementariesFollowContentInsets = false

and then offset the section:

section.contentInsets = NSDirectionalEdgeInsets(top: 66, leading: 8, bottom: 0, trailing: 8)

func createLayout() -> UICollectionViewLayout {
    let config = UICollectionViewCompositionalLayoutConfiguration()
    config.scrollDirection = .horizontal
    let layout = UICollectionViewCompositionalLayout(sectionProvider: { (sectionIndex: Int, layoutEnvironment: NSCollectionLayoutEnvironment) -> NSCollectionLayoutSection? in

        let leadingItem = NSCollectionLayoutItem(
            layoutSize: NSCollectionLayoutSize(widthDimension: .fractionalWidth(1),
                                               heightDimension: .estimated(50)))

        let widthFraction: CGFloat = UIScreen.main.bounds.size.width > UIScreen.main.bounds.size.height ? 0.2 : 0.8
        let containerGroup = NSCollectionLayoutGroup.vertical(
            layoutSize: NSCollectionLayoutSize(widthDimension: .fractionalWidth(widthFraction),
                                               heightDimension: .estimated(50)),
            subitems: [leadingItem])

        let section = NSCollectionLayoutSection(group: containerGroup)
        section.boundarySupplementaryItems = [self.makeHeader()]
        section.supplementariesFollowContentInsets = false
        section.orthogonalScrollingBehavior = .continuous
        section.interGroupSpacing = 16
        section.contentInsets = NSDirectionalEdgeInsets(top: 66, leading: 8, bottom: 0, trailing: 8)
        return section

    }, configuration: config)
    return layout
}

func makeHeader() -> NSCollectionLayoutBoundarySupplementaryItem {
    let widthFraction: CGFloat = UIScreen.main.bounds.size.width > UIScreen.main.bounds.size.height ? 0.2 : 0.8
    let size = NSCollectionLayoutSize(widthDimension: .fractionalWidth(widthFraction),
                                      heightDimension: .absolute(50))
    let sectionHeader = NSCollectionLayoutBoundarySupplementaryItem(layoutSize: size, elementKind: UICollectionView.elementKindSectionHeader, alignment: .top)
    return sectionHeader

}

CodePudding user response:

Add your header as in boundarySupplementaryItems inside your layout declaration.

let layout = UICollectionViewCompositionalLayout(sectionProvider: {

    

    let widthFraction: CGFloat = UIScreen.main.bounds.size.width > UIScreen.main.bounds.size.height ? 0.2 : 0.8
    let size = NSCollectionLayoutSize(widthDimension: .fractionalWidth(widthFraction),
                                  heightDimension: .estimated(50))
    let sectionHeader = NSCollectionLayoutBoundarySupplementaryItem(layoutSize: size, elementKind: UICollectionView.elementKindSectionHeader, alignment: .top)

    section.boundarySupplementaryItems = [sectionHeader]

    return section
}

That should work.

  • Related