Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Horizontally scrolling multiple sections with UICollectionViewCompositionalLayout

Is it possible to use UICollectionViewCompositionalLayout to create a horizontally scrolling collection view that contains multiple sections?

I'm looking to create a layout similar to the emoji keyboard that has multiple sections, each appended to the end of the previous, in one horizontally scrolling "group", with a header stretching across each section.

enter image description here

With the following layout each section is stacked vertically and each scrolls horizontally:

    UICollectionViewCompositionalLayout {
        (sectionIndex: Int, layoutEnvironment: NSCollectionLayoutEnvironment) -> NSCollectionLayoutSection? in

        let leadingItem = NSCollectionLayoutItem(
            layoutSize: NSCollectionLayoutSize(widthDimension: .fractionalWidth(0.7),
                                              heightDimension: .fractionalHeight(1.0)))
        leadingItem.contentInsets = NSDirectionalEdgeInsets(top: 10, leading: 10, bottom: 10, trailing: 10)

        let trailingItem = NSCollectionLayoutItem(
            layoutSize: NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0),
                                              heightDimension: .fractionalHeight(0.3)))
        trailingItem.contentInsets = NSDirectionalEdgeInsets(top: 10, leading: 10, bottom: 10, trailing: 10)
        let trailingGroup = NSCollectionLayoutGroup.vertical(
            layoutSize: NSCollectionLayoutSize(widthDimension: .fractionalWidth(0.3),
                                              heightDimension: .fractionalHeight(1.0)),
            subitem: trailingItem, count: 2)

        let containerGroup = NSCollectionLayoutGroup.horizontal(
            layoutSize: NSCollectionLayoutSize(widthDimension: .fractionalWidth(0.85),
                                              heightDimension: .fractionalHeight(0.4)),
            subitems: [leadingItem, trailingGroup])
        let section = NSCollectionLayoutSection(group: containerGroup)
        section.orthogonalScrollingBehavior = .continuous

        return section

    }
like image 746
Jordan H Avatar asked Apr 20 '26 16:04

Jordan H


1 Answers

You can set the primary scroll direction for the collectionViewLayout to horizontal with the following configuration:

let config = UICollectionViewCompositionalLayoutConfiguration()
    config.scrollDirection = .horizontal

let sectionProvider = ...(your section provider here)

let cvLayout = UICollectionViewCompositionalLayout(sectionProvider: sectionProvider, configuration: config)

Within the sectionProvider you can create a header pinned to the top of each section as follows:

let headerSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: .estimated(40))
let headerSupplementary = NSCollectionLayoutBoundarySupplementaryItem(
            layoutSize: headerSize,
            elementKind: UICollectionView.elementKindSectionHeader,
            alignment: .topLeading)
section.boundarySupplementaryItems = [headerSupplementary]

This setup should achieve the scrolling behaviour you desire. Within each section you could use the following group to achieve the same grid layout as the emoji keyboard:

let group = NSCollectionLayoutGroup.vertical(layoutSize: groupSize, subitem: item, count: 5)
like image 107
Apptek Studios Avatar answered Apr 22 '26 08:04

Apptek Studios