UICollectionView compositional layout with orthogonal scrolling and a different size for last cell

We’re attempting to use UICollectionView compositional layout to describe a section layout, but it’s giving us some trouble.

What we’d like to achieve:

  • A total of 7 cells
  • 3 cells stacked, each 30% height and 100% width, with orthogonal scrolling to see the next 3
  • When the user reaches the last cell, it would be 100% height and 100% width of the container.

ASCII art and screenshots of the imperfect example are below.

Our starting point was Apple’s example code, specifically OrthogonalScrollingViewController, but what we’ve found is if we expand the widths there, the height settings seem to longer be respected.

The most basic version of a layout that we tried is this:

  func createLayout() -> UICollectionViewLayout {
    let layout = UICollectionViewCompositionalLayout {
      (sectionIndex: Int, layoutEnvironment: NSCollectionLayoutEnvironment) -> NSCollectionLayoutSection? in
      
      // Small items at roughly 30% of the container height.
      let smallItem = NSCollectionLayoutItem(
        layoutSize: NSCollectionLayoutSize(
          widthDimension: .fractionalWidth(1.0),
          heightDimension: .fractionalHeight(0.3)
        )
      )

      // The large item should be 100% of the container width.
      let largeItem = NSCollectionLayoutItem(
        layoutSize: NSCollectionLayoutSize(
          widthDimension: .fractionalWidth(1.0),
          heightDimension: .fractionalHeight(1.0)
        )
      )

      // We want 3 items to appear stacked with orthogonal scrolling.
      let smallItemGroup = NSCollectionLayoutGroup.vertical(
        layoutSize: NSCollectionLayoutSize(
          widthDimension: .fractionalWidth(1.0),
          heightDimension: .fractionalHeight(1.0)
        ),
        subitem: smallItem,
        count: 3
      )
      
      let containerGroup = NSCollectionLayoutGroup.horizontal(
        layoutSize: NSCollectionLayoutSize(
          widthDimension: .fractionalWidth(1),
          heightDimension: .fractionalHeight(0.5)
        ),
        subitems: [smallItemGroup, largeItem]
      )
      
      let section = NSCollectionLayoutSection(group: containerGroup)
      section.orthogonalScrollingBehavior = .paging
      
      return section
    }
    
    return layout
  }

We’ve tried many variations of nested groups and using the .vertical and .horizontal initializers, but each of them has the same result: The last cell is always the same size as all the others.

  //   +------------------------------+                  These would be off-screen
  //   | +-------------------------+  |  +-------------------------+  +-------------------------+
  //   | |            1            |  |  |            4            |  |                         |
  //   | +-------------------------+  |  +-------------------------+  |                         |
  //   | +-------------------------+  |  +-------------------------+  |                         |
  //   | |            2            |  |  |            5            |  |            7            |
  //   | +-------------------------+  |  +-------------------------+  |                         |
  //   | +-------------------------+  |  +-------------------------+  |                         |
  //   | |            3            |  |  |            6            |  |                         |
  //   | +-------------------------+  |  +-------------------------+  +-------------------------+
  //   |                              |
  //   |                              |
  //   |                              |
  //   |     rest of the screen       |
  //   |                              |
  //   |                              |
  //   |                              |
  //   |                              |
  //   +------------------------------+

The last cell in the third screenshot, (0,6), is the one we want 100% height of the section.

Is there a way to achieve this layout where the last cell is 100% of the section height?

Replies

in most cases you need 2 sections (1 section for big cell)