How to create a list with Compositional Layout

The easiest way for creating standard list layouts with the new APIs available from iOS 14.

Published: July 5, 2022
See books

Lists are one of the most common layouts in iOS apps, and while in the past, we created these with the UITableView, we can quickly achieve lists with UICollectionView, which gives you more flexibility.

Simple collection view list

In this post, we will look at creating the simplest list possible. It takes just a few lines of code.

Like this:

let configuration = UICollectionLayoutListConfiguration(appearance: .plain)

let layout = UICollectionViewCompositionalLayout.list(using: configuration)

collectionView.setCollectionViewLayout(layout, animated: false)

And we could compress this code even further…

The code above will get you the most basic list that automatically handles the sizes of each item. I recommend using this new list as a default unless you have needs that cannot be met with this API.

You can also easily get the “inset grouped” style popular in iOS. Just by creating different configuration:

var configuration = UICollectionLayoutListConfiguration(appearance: .insetGrouped)

This list will also handle separators for you.

Basic configuration

Above I used extra constant to store the UICollectionLayoutListConfiguration because it offers a lot of useful customizations. Let’s look at a few:

configuration.backgroundColor = .systemTeal
configuration.showsSeparators = false

We have now changed the background color of the collection view and turned off the separators.

Another useful property is headerTopPadding, which allows us to control the space above each section header. Note that this has been added in iOS 15.

configuration.headerTopPadding = 32

How to add headers and footer to list layout

Configuring the list layout to show headers or footers is also fairly straigthforward thanks to the configuration:

configuration.headerMode = .supplementary
configuration.footerMode = .supplementary

The above will configure the layout to use the supplementaryViewProvider on your Diffable data source to provide the header view.

Per section configuration

While the code above is nicely concise, there are limitations. For example, let’s say you have multiple sections and want to show headers for only some sections.

The only way (that I know of) is to use the list configuration but to configure it section by section.

We will use the UICollectionViewCompositionalLayout initializer with the section provider, which lets us return different sections based on the index.

Basic example looks like this:

let layout = UICollectionViewCompositionalLayout { [unowned self] index, environment in

    switch index {
    case 0:
        var configuration = UICollectionLayoutListConfiguration(appearance: .insetGrouped)

        configuration.headerMode = .supplementary

        return .list(using: configuration, layoutEnvironment: environment)

    default:
        let configuration = UICollectionLayoutListConfiguration(appearance: .plain)

        return .list(using: configuration, layoutEnvironment: environment)
    }

}

We would first get the section from our Diffable data source in real code and switch on that.

As you can see, the first section will be .insetGrouped with a header, and all the remaining sections will be plain lists without supplementary views.

This approach also has the benefit that we can mix the list layout with any other kinds of layouts Compositional Layout supports. You could have horizontal sections mixed with the lists, for example.

Example code on GitHub

You can also check out my GitHub repository, which has many examples that use various parts of Compositional Layout and Diffable.

Bluesky logo

Follow on Bluesky to not miss new posts

Filip Němeček profile photo

WRITTEN BY

Filip Němeček Mastodon

iOS blogger and developer with interest in Python/Django.

iOS blogger and developer with interest in Python/Django.