adamjansch
adamjansch

Reputation: 1371

Horizontal UICollectionViewCompositionalLayout displaying section headers over item cells

I am attempting to use UICollectionViewCompositionalLayout to create this design:

UICollectionViewCompositionalLayout desired layout

The intention here is for the collection view to scroll horizontally, with the items also scrolling vertically when they overflow using NSCollectionLayoutSection's orthogonalScrollingBehavior property.

This is the layout I have right now:

private lazy var collectionViewLayout: UICollectionViewLayout = {
    let sectionWidth: CGFloat = 256.0

    let layoutItemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: .estimated(50.0))
    let layoutItem = NSCollectionLayoutItem(layoutSize: layoutItemSize)

    let layoutGroupSize = NSCollectionLayoutSize(widthDimension: .absolute(sectionWidth), heightDimension: .fractionalHeight(1.0))
    let layoutGroup = NSCollectionLayoutGroup.vertical(layoutSize: layoutGroupSize, subitems: [layoutItem])
    layoutGroup.interItemSpacing = .fixed(8.0)

    let layoutSectionHeaderItemSize = NSCollectionLayoutSize(widthDimension: .absolute(sectionWidth), heightDimension: .absolute(150.0))
    let layoutSectionHeaderItem = NSCollectionLayoutBoundarySupplementaryItem(layoutSize: layoutSectionHeaderItemSize, elementKind: UICollectionView.elementKindSectionHeader, alignment: .top)

    let layoutSection = NSCollectionLayoutSection(group: layoutGroup)
    layoutSection.contentInsets = NSDirectionalEdgeInsets(top: 24.0, leading: 24.0, bottom: 24.0, trailing: 24.0)
    layoutSection.boundarySupplementaryItems = [layoutSectionHeaderItem]
    layoutSection.interGroupSpacing = 8.0

    let layoutConfiguration = UICollectionViewCompositionalLayoutConfiguration()
    layoutConfiguration.scrollDirection = .horizontal
    layoutConfiguration.interSectionSpacing = 16.0

    return UICollectionViewCompositionalLayout(section: layoutSection, configuration: layoutConfiguration)
}()

The result is:

UICollectionViewCompositionalLayout actual layout

Any ideas as to where I'm going wrong?

Upvotes: 0

Views: 3047

Answers (1)

adamjansch
adamjansch

Reputation: 1371

3 months later and no direct solutions to this one (either here, nor via bug report from Apple). So to get the design I was after I ended up reconfiguring the view structure.

In short, to get vertically-scrolling columns with a pinned header within a horizontally-scrolling collection view I placed a table view in the collection view cell, with the header elements above it, all in a stack view.

I kept the UICollectionViewCompositionalLayout on the collection view, which has been simplified:

private lazy var collectionViewLayout: UICollectionViewLayout = {
    let layoutItemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: .fractionalHeight(1.0))
    let layoutItem = NSCollectionLayoutItem(layoutSize: layoutItemSize)
    
    let fractionalWidth: CGFloat = (Device.current.isPad) ? 0.5 : 1.0
    let layoutGroupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(fractionalWidth), heightDimension: .fractionalHeight(1.0))
    let layoutGroup = NSCollectionLayoutGroup.vertical(layoutSize: layoutGroupSize, subitems: [layoutItem])
    let layoutSection = NSCollectionLayoutSection(group: layoutGroup)
    
    let layoutConfiguration = UICollectionViewCompositionalLayoutConfiguration()
    layoutConfiguration.scrollDirection = .horizontal
    
    return UICollectionViewCompositionalLayout(section: layoutSection, configuration: layoutConfiguration)
}()

Upvotes: 1

Related Questions