Leverage the UIHostingConfiguration
This post will try to illustrate how to incorporate a SwiftUI view inside a
UICollectionView , alongside it will provide a quick introduction to using modern collection views and diffable data sources.
It will utilize the new
UIHostingConfiguration API that has been introduced for iOS and tvOS 16 in WWDC 22. You will need Xcode 14 (beta as of this writing) if you wanted to try this.
We will create a very minimal
ToDo List screen that will display the list of
ToDo list items and their state. The
ToDo list will be a collection view and its cells will be composed as a SwiftUI view.
When we complete the screen will look like the below. A complete example of what is being discussed below can be found here.
This follows a previous post about using a SwiftUI view inside a UIKit view.
ToDoListdata structure consists of an array of
ToDoListItems. This relationship is modeled as shown below. The Todo list data we have will have ToDo lists for
Let’s create a SwiftUI view that will display an individual
ToDoListItem as below.
The view above uses another SwiftUI view,
TaskStatus. It displays the status of the
ToDo list item (completed or pending) as a system Image icon depending on the status.
We will create a
UIViewController class called
ToDoListViewController. In the
viewDidLoad method of the class we will do the following.
- Create and setup the collection view using a compositional layout (see discussion in next section) and insert it as a subview.
- Set the collection view diffable data source and connect it to the collection view. This will also set it up to use the SwiftUI view.
- apply data to the diffable data source using snapshot
We will discuss the working of functions in
viewDidLoad , the collection view layout and datasource in the rest of the post below.
Collection views are initialized using a
UICollectionViewLayout property. This defines how the cells are laid out in a collection view. Since iOS 13 we have been provided with a new layout API called
UICollectionViewCompositionalLayout , as Apple puts it “A layout object that lets you combine items in highly adaptive and flexible visual arrangements”. This layout also introduced the concept of Section, Group & Item.
Sections have Groups inside them, and Groups have items in them. In our case the section corresponds to either Home or Office and the item is an individual
In our example a ToDo list we will span the item across the whole width of the screen (
fractionalWidth(1.0) ) and sets it height to be the height of the group it’s in (
Similarly, we want the section to span the whole width & have an absolute height of 60 (
Diffable data source and Cell registration
Since iOS 13 and tvOS 13, we have the API for
UICollectionViewDiffableDataSource which has greatly simplified how collection views source their data.
We use it to connect a collection view to its data source and define its “cell provider”. A cell provider is a function that returns a cell for a collection view. Its
init signature is
Alongside the diffable data source we also have an API to do a “cell registration” (also achievable using older APIs such as
register(_:forCellWithReuseIdentifier:)). The cell registration API offers a way to configure a cell for display.
Now the power of cell registration in terms of SwiftUI comes when we use it to set the cells
contentConfigurationproperty. We use it to supply the
UIHostingConfigurationwhich is a new API (iOS 16) that allows us to specify a SwiftUI view as its content. As we see above we have set the content to
CellView(toDoListItem: item), where
CellViewis a SwiftUI view we created earlier.
Following this, we use the
To complete the data source we finally set the
supplementaryViewProvider property of the data source to return a regular UIKit view
The last step to bring the collection view to life is to apply some data into it. Again this is done using a recent API (iOS 13) called
A diffable data source utilizes the concept of Section and Item that we discussed before. We initialize a diffable data source object using a SectionIdentifierType
ToDoListItemType and a
ToDo list items belong to either the “Home” or “Office” section. We use the
appendItems API followed by the
apply API on the datasource to set the data.
When we apply a snapshot to the collection view datasource the collection view automatically reloads the data !
Collection views have improved quite a lot in terms of their developer experience since iOS 13 with the introduction of Compositional layout and diffable data sources. Along with the ever-improving support and improvements with SwiftUI, we are now able to leverage the benefits in existing
The main concepts to grasp when working with these components is the understanding of
DiffableDataSource, Compositional layouts and Cell registration.
A complete example of an Xcode project can be found here.