Working with collection view may seem to be complicated. One of the main reasons developers choose table views over collection views is that you don’t have to “suffer” with layout, you only specify the height of a row and that’s it. Moreover, it’s pretty straightforward how to make table view cells self size and it bribes many developers. I personally believe that using collection view is better option because of its flexibility and more control over the layout.
In this article I’m going to describe number of ways how we can make collection view cells self size.
All of the ways require setting estimatedItemSize property of collection layout to UICollectionViewFlowLayout.automaticSize.
When you set estimatedItemSize as above you make collection view query each cell for its actual size using this method implemetation. In the implementation you call super implementation and then mutate the attributes size as you need. Here is an example:
The downside of this approach is that cell is unaware of its parent frame so the cell cannot size its width properly.
Fortunately, we can tell our cells the width they should fit in.
Let’s define simple protocol:
Now we can modify our dataSource cellForItemAt indexPath method to check whether the cell is BoundingWidthAdoptable and if so call adoptBoundingWidth method providing content width of the collection view:
The cell can be implemented like this:
That’s all for this approach.
Using auto-layout for auto-sizing
This approach allows as not to calculate cell size at all.
All you have to do here is properly configure constraints of your cells’ content (like labels, images etc.) to make auto-layout understand how it should size the cell, just the same way you do it in self-sizing table view cells. But before you do this, you must configure cell’s contentView constraints as well:
Here I use SnapKit, hope you understand the essence.
From now on your cell will automatically calculate its height, but be 100 points wide.
We fix this the same way we fixed width problem in the first approach. But now the implementation is a bit different:
That’s all. Hope this will help someone.