New in iOS 16 — Self-resizing UICollectionView Cells
Build an expandable UICollectionView using compositional layouts and diffable data sources in iOS 16
Creating dynamic Table View or Collection View cells is a challenge that most iOS developers have struggled with at some point. From using estimatedRowHeight
to creating custom UICollectionViewLayout
— setting dynamic sizes for UICollectionViewCell
s requires implementing a bunch of methods — and I’ve always fallen back to recipe codes — despite the introduction of compositional layouts
Gladly, in WWDC 2022, Apple has brought a major enhancement to its UIKit framework. With iOS 16, Table View and Collection View cells can now self-resize based on the content through the selfSizingInvalidation
property which is enabled by default.
To resize a cell manually/programmatically — we can call the the invalidateIntrinsicContentSize()
. If you’re looking to resize a cell without animation — call the invalidateIntrinsicContentSize()
inside UIView.performWithoutAnimation
function.
Now that we’ve learned about this nice upgrade, let’s build our modern collection view iOS app.
In the following sections, we’ll build an expandable collection view using the iOS 16 features — without relying on reloading items or creating custom cells.
For the uninitiated, with iOS 15, Diffable Data Sources had introduced a new way to update cells in place without replacing the existing cells. This works through the reconfigureItems
function.
Building Blocks
- Create a Collection View by using Compositional Layouts
- Add dummy data. In our case, we’ll be feeding our Collection View with an array of movies ( with description details) through a Diffable Data Source.
- Expand and collapse Collection View cells on select. For our use case, we’ll show and hide movie details.
Let’s get started.
Setting Up Our Data Model
We’ll hold the data in a Movie
class as shown below:
For the sake of simplicity of this example, we’ve set the movie name
as the unique identifier. The showDetails
flag will be used to expand and collapse the Collection View.
Section
in the above code is an enum that conforms to Hashable
implicitly. It holds two values — signifying two sections in our collection view.
Setting Up Our Collection View
Here’s the code to set up your UICollectionView
layout and configuration:
Leave aside //1
and //2
(which is meant to configure the diffable data source), the rest of the code configures our Collection View.
For starters, the List
layout was introduced in iOS 14 and is built on top of compositional layouts to give a TableView-like design experience. In the above code, we leverage it to set our configuration style which then gets passed to the compositional layout — which eventually is passed to the UICollectionView
initializer.
Now let’s take a look at our dataSource
.
Configuring Our Diffable Data Source
Here’s the code for our makeDataSource()
function:
A lot is happening in the above code, and if building modern collection views is new to you, here are a few inferences you should focus on:
UICollectionView.CellRegistration
struct was introduced with iOS 14. And it implicitly takes care of cell registration when passed inside thedequeueConfiguredReusableCell
. So, say goodbye to registering cells using identifiers.UICollectionViewListCell
is the concrete class that bringsUITableView
-like cell styling. We’ve invoked thedefaultContentConfiguration
function on that cell. After fetching that configuration, we set the cell label text and description based on a boolean flag logic.- The
cellProvider
closure insideUICollectionViewDiffableDataSource
is analogousto collectionView(_:cellForItemAt:)
Now, that we’ve configured our dataSource, here’s our dummy data:
Reconfiguring Collection View Items
To create an expandable collection view cell, we simply invert the showDetails
value inside the didSelectItem
delegate method:
The rest of the logic is self-explanatory.
Output
Here’s the final app in action:
Another example could be — adding a text field in the collection view cell and seeing how it expands automatically as type.
You can find the full source code on this GitHub Repository.
Thanks for reading.