How To Create Custom UICollectionViewListCell Using SwiftUI in iOS 16 | by Lee Kah Seng

Define your own layouts

image by author

Whenever I use a storyboard or XIB file to create a custom UICollectionViewor UITableView cell layout, I always wonder, wouldn’t it be great if I could use SwiftUI to define the layout? In this year’s WWDC (2022), Apple finally made that happen.

In this article, we will explore what it takes to build the following list using a collection view and SwiftUI.

How To Create Custom UICollectionViewListCell Using SwiftUI
The sample app

At the end of this article, you will learn:

  1. How to use the UIHostingConfiguration
  2. How to adjust the cell height
  3. How to adjust the separator inset
  4. How to adjust the cell’s layout margin

There are many topics to be covered here, so let’s get right into it.

Before diving into the main topic, there are a few things that we need to get in place. First, import the SwiftUI module to your view controller class.

import SwiftUI

After that, define the following data types that will act as the data model of our list:

Next up, configure our collection view to use a list layout configuration.

In the code above, notice that we are not using a diffable data source. A diffable data source is not mandatory when creating a custom cell using SwiftUI. Furthermore, since the list we are building shows a static data set, using a traditional data source is much more straightforward and easier to understand.

Lastly, let’s implement the required UICollectionViewDataSource methods:

Notice the swiftUICellRegistration used in the code above, we will be working on that in a moment. For now, just keep in mind that using the swiftUICellRegistration is how we link up our custom SwiftUI cell with the collection view.

With all that out of the way, we can now get into the fun stuff.

Before iOS 16, to create a custom UICollectionViewListCell, we need to create a subclass of UICollectionViewListCell and define a custom configuration object that conforms to the UIContentConfiguration protocol, which is somewhat troublesome.

With the introduction of UIHostingConfiguration in iOS 16, it is now possible to define the layout and content of a custom cell using SwiftUI, eliminating the need to create a UICollectionViewListCell subclass and a custom configuration object.

Based on Apple’s documentation, the UIHostingConfiguration struct is conformed to the UIContentConfiguration protocol. Therefore we can use it during cell registration like so:

From the code above, there are two things you need to be aware of.

First, the cell type that we use for cell registration is UICollectionViewListCell (not UICollectionViewCell). Since we are building a list, using UICollectionViewListCell will gain us some of its useful functionalities such as:

  1. The ability to display cell accessories
  2. The ability to adjust the separator inset (more on that later)
  3. Various cell appearances (based on the collection view’s layout configuration)

Second, notice that we are defining the cell registration as an instance variable (swiftUICellRegistration). As you have seen earlier, this enables us to use swiftUICellRegistration in the collection view’s data source method.

OK, enough said. Let’s define the cell’s layout and content using SwiftUI to see everything in action.

At this point, if you try to run the sample code, you will see the following cells being populated.

Using UIHostingConfiguration to create custom cell layout
The result of using UIHostingConfiguration to create custom cell layout

Adjusting the cell height

From the image above, you should notice that our current cell height is a bit smaller than what we are expecting. As mentioned in one of my previous articles, UICollectionViewListCell is a self-sizing cell. This means it will automatically adjust its size based on its layout and content.

With that in mind, we can easily increase the cell height by simply increasing the height of the HStack.

Note: Make sure to set the HStack‘s frame before setting the yellow color background view, or else the yellow background view height will not increase accordingly.

Here’s the end result:

Adjust cell height when using UIHostingConfiguration
Cells with adjusted height

Adjusting the separator inset

Currently, the separator’s leading edge is aligned with the text in the cell. This is the default behavior inherited from the UICollectionViewListCell. Unfortunately, this is not what we want.

To achieve what we want, we can use the alignmentGuide modifier like so:

What the above code did was align the separator leading edge with the HStack leading edge and align the separator trailing edge with the HStack trailing edge. Here’s what we will get:

Adjusting cell separator inset when using UIHostingConfiguration
Adjusted cell separator inset

Adjusting the cell’s layout margins

By default, the cell’s SwiftUI content is inset from the edges of the cell, based on the cell’s layout margins in UIKit. To overwrite the default margin, we can use the UIHostingConfiguration’s margins modifier to do so.

With that, our custom cell has reached its final form.

Adjusting cell content margins when using UIHostingConfiguration
Cell with adjusted content margins

Now that we have finished composing our custom cell using SwiftUI, we can perform simple refactoring by creating a dedicated SwiftUI view for our custom cell layout.

With that in place, we can now create the UIHostingConfiguration like so:

Notice how we configure the MyFirstSwiftUICell‘s content by passing in the itemobject during initialization.

With this simple refactoring, we have successfully improved the readability of our code when creating a UIHostingConfiguration. Furthermore, we also converted our custom cell’s layout into a reusable component.

The example I use throughout this article is mainly focused on creating a custom UICollectionViewListCell, but that doesn’t mean that you cannot use UIHostingConfiguration to create a custom UICollectionViewCell. In fact, according to Apple, UIHostingConfiguration is designed to be able to work on both UICollectionViewCell and UITableViewCell.

However, do notice that UIHostingConfiguration is only available in iOS 16 and above. If your app still needs to support an iOS version lower than iOS 16, you might consider falling back to the non-SwiftUI way.

Last but not least, here’s the full sample code.

Thanks for reading.

Want to Connect?Reach me out on Twitter if you have any questions.

News Credit

%d bloggers like this: