Simplify collection view compositional layout with a DSL
At the WWDC19 Apple introduced a class UICollectionViewCompositionalLayout. This new API allows us to create a custom layout
in a declarative and composable way. It is available from iOS 13, tvOS 13 and macOS 10.15.
A compositional layout is composed of sections containing groups, and the groups contain items.
There are also supplementary items and boundary supplementary items for headers, footers or any custom supplementary view like badges.
One of the best feature of compositonal layouts is the ability to have multi-dimensional browsing with the orthogonal scrolling behavior (see gif above).
Here is for example the code for the layout with nested groups and orthogonal scrolling:
This code works well, but it has some issues:
it is quite verbose
it is not easy to read
it is hard to visualize what this layout is building
Let’s see in the following section how we can tackle these problems.
Domain-specific language for UICollectionViewCompositionalLayout
With the Swift 5.1 @_functionBuilder (now @resultBuilder in Swift 5.4) and SwiftUI being popular,
a domain-specific language (DSL) can be a great way
to improve the UICollectionViewCompositionalLayout API.
By looking at the SwiftUI DSL created by Apple, we can model a similar syntax to rewrite the previous example into something like that:
This code has several advantages compared to the UIKit API:
it is shorter
it is easy to read with a SwiftUI like syntax
it is way more visual: the syntax follows the structure of the layout
Here is another example, where we focus on a simple list layout:
With UIKit, we would implement this layout like this:
The same layout with the DSL becomes:
The CompositionalLayoutDSL library
If you liked the proposed DSL syntax, here’s great news:
The previous examples of code using the DSL can actually be used right now with our new
library CompositionalLayoutDSL!
This library gives you the DSL, and it also gives you the ability to compose your layout in a SwiftUI manner,
making it all the easier to reuse custom layouts, as well as improving readability.
Let’s take the following layout as an example:
You can create your own structs to represent custom groups, making them reusable in your project:
Creating your own structs to represent your objects is possible for all components of a compositional layout.
Here is an example that conforms to LayoutSection:
And when you want to use the custom section you configure your collection view like that:
All the other compositional layouts availables in the
Apple sample code
have also been adapted to use the DSL, you can find the changes in
this repository.
If you want to see more of this library in action you can have a look at the example app.
Conclusion
Compositional layout has been introduced by Apple in 2019 and gives you the power of creating great layouts easily.
While declarative, the UIKit API is quite verbose and therefore hard to read and visualize.
To solve those issues we have created a new library CompositionalLayoutDSL
which provides a DSL that makes compositional layout code shorter, more readable and reusable.
CompositionalLayoutDSL requires at least Swift 5.1, and is available
on the platforms supporting the compositional layout API (iOS 13+, tvOS 13+ and macOS 10.15+). You can use this library in
your project using the Swift Package Manager, CocoaPods or Carthage.