How to create grid with Compositional Layout

Let's look at creating basic grid layouts using Compositional Layout.

While a grid layout is not as popular choice as a list layout, in some cases (like displaying a photos or other data in a "cards" fashion) it is indispensable. Thanks to Compositional Layout creating grids is easier than it used to be with the flow layout, it may not be very intuitive the first few times.

That's why I decided to dedicate this post to grid layouts. (And I also want a handy reference for the future when I run into issues 😅)

In my previous post, which explored in detail the NSCollectionLayoutGroup, I have shown one way of creating grid layout. In this post we will explore the alternative.

The "trick" is to combine fractional sizes of the NSCollectionLayoutItem with the sizing of NSCollectionLayoutGroup.

I think it is better to show the code and then explain. Here is the relevant part:

let itemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(0.5), heightDimension: .fractionalHeight(1.0))
let item = NSCollectionLayoutItem(layoutSize: itemSize)
let groupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: .fractionalWidth(0.5))
let group = NSCollectionLayoutGroup.horizontal(layoutSize: groupSize, subitems: [item])

We first declare the item and tell Compositional Layout that the width will be 50% of the available space. Next we move to the group and set its height to be .fractionalWidth(0.5). So here we are using the width (which is 50% thanks to the item size) as the height. Which means we will get perfect rectangles and there will be two on each row.

With this done, we can create the section and then the entire layout:

let section = NSCollectionLayoutSection(group: group)
let layout = UICollectionViewCompositionalLayout(section: section)
return layout

And with that, our grid layout is complete.

Compositional Layout - simple grid

If you wanted three items on a single row, we would modify both the .fractionalWidth(0.5) values to .fractionalWidth(1/3). Same for four items (.fractionalWidth(1/4)) and five (.fractionalWidth(1/5)).

It mostly does not matter which style of fractions you use, however in the case of thirds, the 1/3 will be more precise than 0.333 although you could add as many threes as you want here 😄

This fractional value also doesn't have to be static, you can make it dynamic and let the user change the size of the grid items. These examples are available on GitHub.

Uses: Xcode 12 & Swift 5.3

Follow me on Twitter for latest updates and news