This article is part of a 4-part series on Building Custom Collection View Layouts.
- The components of UICollectionViewLayout
- Building a custom UICollectionViewLayout from scratch
- Integrating self-sizing cells in a custom layout
- Animating insertions and deletions
You’d be hard-pressed to get very far into iOS development without encountering
UICollectionView. Since it was released in iOS 6, it has become an integral part of app development.
And it’s easy to see why. Its sheer versatility makes it the ideal tool for so many different types of UI. From grids of photos, to whole calendars, there’s little that you can’t do with
However, customizing your own layout can be an extremely frustrating experience.
This article is a quick refresher on the different components that make
UICollectionViewLayout work its magic. It’ll lay the groundwork for the rest of the series where we make our own layout.
Today, we’ll be covering:
- What are the different kinds of views that can be laid out with
- How are those views laid out?
- What is the one main job of
Let’s jump in!
The 3 types of views that make or break UICollectionView
UICollectionViewLayout is the main reason why
UICollectionView are so different. When you create a
UITableView, you supply it a data source and you’re good to go. Its layout is always the same.
UICollectionView, on the other hand, doesn’t only have a data source to drive its UI, it also has a dedicated layout object. This is the object that lays out the different views on the screen. In other words, two different collection views could have the same data — and even the same cells — but look completely different.
There are three types of views that our layouts can deal with. Let’s take a look at each and how they differ from one another.
First and foremost, we have
UICollectionViewCell. This is the one we’re all familiar with.
Its job is to display the data. As such, it’s supplied by the data source via
cellForItem(at indexPath:). Since it’s considered the data-driven component, won’t bave direct access to the cell from inside your layout. Instead, you’re encouraged to pass data via other means, which we’ll cover soon. However, when designing your cells, a good rule of thumb is to assume that the layout won’t be modifying them at all.
You can use as many different kinds of cells as you want, but they must all make sense inside of a single sequence of index paths. For example, you cannot have 2 different cells at index (0,0). One of them needs to logically exist before the other.
Now onto my favourite named component in UIKit,
(Is that ever a mouthful!)
Supplementary views are used to display UI that are related to both the layout and the data. A common example of supplementary views are headers and footers. These are views that add an extra layer of meaning to the data, without being a part of the data itself. They are registered on the
UICollectionView and created by the data source.
You can have multiple different supplementary views in your layout. They are differentiated by a unique key and they each have their own reuse pools, just like
UICollectionViewCell. New instances should be dequeued so as to keep resource use to a minimum.
If you want to create your own supplementary view, you should subclass
UICollectionViewReusableView (which happens to be the base class of
UICollectionViewCell as well).
A decoration view is a view that is driven by the layout instead of by the data. In this way, it’s like the opposite of a cell. It’s registered in the layout and created by the layout.
A great example of
UICollectionViewDecorationView is the gradient background behind the rows of books in the iBooks app. Whether you have 0 books or a thousand books, they will always be laid out the same way.
Decoration views work much the same way as supplementary views do. You can make your own by overriding
In practice, supplementary views are far more common, especially on iPhone where screen real estate is at a premium and chrome is kept to a minimum.
How these things are laid out
In order to lay out these components in the collection view, our layout object needs to supply the collection view with
Among other things, layout attributes specify the frame of the view, its z-index, and any transforms you’d like to apply. Once the collection view is supplied layout attributes for supplementary views and decoration views, it’ll query the data source or layout object to supply those views.
When you create your own layout, the bulk of the work will revolve around calculating frames in order to build these
UICollectionViewLayoutAttribute objects and get everything to display correctly. If you’re used to working exclusively with Auto Layout, manually calculating frames might be new. You’ll need to get your
CGRect math skills involved 😇
A word of warning: we’re not talking about self-sizing cells just yet. Getting
UICollectionViewLayout and self-sizing cells to play nicely together is a whole other ball game, and we’ll get to that in part 3 of the series.
The true job of UICollectionViewLayout
Now that we know the main components involved in
UICollectionViewLayout, we can reason about its true purpose.
UICollectionViewLayout’s purpose is create, cache and supply
UICollectionViewLayoutAttributes for the various elements in its associated
That’s it. All the layout does is calculate where the views go, and supplies that information to the collection view.
It seems obvious in hindsight, but when you’re down in the weeds overriding a dozen methods, it’s easy to lose track of the big picture. When working on your own layout, the only thing you need to concern yourself with is creating the correct layout attributes. Voilà.
A Quick Recap
So there you have it! In this article, we saw how:
UICollectionViewCellis driven by data.
UICollectionViewSupplementaryViewis driven by the data and the layout.
UICollectionViewDecorationViewis driven by the layout.
- They are all laid out using
- And the whole purpose of
UICollectionViewLayoutis simply to supply these layout attributes to
In the next article in the series, we’ll be diving into
UICollectionViewLayout and creating our own layout from scratch!