What’s New in iOS 14 UICollectionView?

Out-of-the-box support for TableView List, a new cell registration technique, and enhancements in DiffableDataSources

Collection Views didn’t exactly make their way into SwiftUI during WWDC 2020, but that didn’t stop UICollectionView from receiving some powerful new updates.

CompositionalLayouts and DiffableDataSources were introduced in iOS 13 CollectionViews and brought more flexibility in constructing layouts and data sources for our UICollectionView.

With iOS 14, there are three new additions to the CollectionView APIs for layouts, data sources, and cells — the three pillars of constructing collection views:

  • Lists are a new addition to CompositionalLayouts and bring a UITableView-like appearance in CollectionViews.

  • UICollectionView.CellRegistration lets you configure cells in a completely different way using new Configuration APIs. Also, there’s a new UICollectionViewListCell concrete class that provides cells with list-like content styling by default.

  • Diffable Data Source now includes Section Snapshots to allow more updating data on a per-section basis. This is useful in building Outlined Styled lists, a new hierarchical design introduced in iOS 14.

In the next few sections, we’ll discuss the first two additions. Let’s see how to construct layouts and cells in UICollectionView in the new iOS 14 way.

iOS 14 Cell Configuration and Registration

iOS 14 introduces a brand new Cell Configuration API for configuring our CollectionView and TableView cells.

This means that we don’t need to set properties directly on the UITableViewCell and UICollectionViewCell like we did earlier.

The new configuration API lets us use a content configuration to set the cell’s content and styling or update it based on different states:

let cellRegistration = UICollectionView.CellRegistration<UICollectionViewCell, String> { cell, indexPath, name in
var content = UIListContentConfiguration.cell()
content.text = name
cell.contentConfiguration = content
}

For UICollectionViews, we have a new UICollectionViewListCell. We can directly fetch its default configuration in the following way:

var content = listCell.defaultContentConfiguration()

In doing so, we’re able to get rid of using cell identifiers and the obligatory if let and guard let statements we used to write to ensure that the cell was registered.

More importantly, we’re not directly accessing the cell’s label and image property anymore, which allows us to compose configurations that can be used across TableViewCollectionView, and custom cells.

Aside from contentConfiguration, there’s also a backgroundConfiguration that we can leverage to set background appearance properties and also a leadingSwipeActionsConfiguration and trailingSwipeActionsConfiguration to easily embed UITableView-like swipe behavior directly in our UICollectionView cell implementation.

The new UICollectionView.CellRegistration structure that we just created automatically takes care of cell registration when passed inside the dequeueConfiguredReusableCell. You don’t need to register cells using identifiers anymore.

iOS 14 New List Layouts for CollectionViews

Taking a cue from the UICollectionViewListCell we discussed in the previous section, we now have a new List Layout built on top of compositional layouts.

All it takes to quickly set up this layout is passing in the UICollectionViewListConfiguration, which could be set as groupedinsetGroupedsideBar, and sideBarPlain in addition to the following plain appearance:

let config = UICollectionLayoutListConfiguration(appearance: .plain)
let layout = UICollectionViewCompositionalLayout.list(using: config)

The good thing about the new Lists support in UICollectionView is that it provides out-of-the-box support for self-sizing cells.

We can also create lists on a per-section basis by passing in the NSCollectionSectionLayout.list within the compositional layout.

Customizing header and footer for lists in UICollectionView is a bit different from what we did in UITableView.

You’d need to invoke the headerMode or footerMode on the list configuration in the following way:

config.headerMode = .supplementaryconfig.footerMode = .supplementary

Subsequently, you’d need to provide the view by invoking supplementaryViewProvider on the Diffable Data Source, wherein you can set the dequeueConfiguredReusableSupplementary function and pass in the header configuration.

Now let’s combine the new features above (Cell Configuration API, List Layout, and Registrations).

We’ve set up a simple UICollectionView in our UIViewController, as shown below:

class ViewController: UIViewController {
var items = Array(0...100).map { String($0) }
var collectionView : UICollectionView!
private lazy var dataSource = makeDataSource()
override func viewDidLoad() {
super.viewDidLoad()
let config = UICollectionLayoutListConfiguration(appearance: .insetGrouped)
let layout = UICollectionViewCompositionalLayout.list(using: config)
collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout)
self.view.addSubview(collectionView)
//add autolayout constraints
collectionView.dataSource = dataSource
var snapshot = NSDiffableDataSourceSnapshot<String,String>()
snapshot.appendSections(["Section 1"])
snapshot.appendItems(items)
dataSource.apply(snapshot, animatingDifferences: true)
}
func makeDataSource() -> UICollectionViewDiffableDataSource<String, String> {
let cellRegistration = UICollectionView.CellRegistration<UICollectionViewListCell, String> { cell, indexPath, name in
var content = cell.defaultContentConfiguration()
content.text = name
cell.contentConfiguration = content
}
return UICollectionViewDiffableDataSource<String, String>(
collectionView: collectionView,
cellProvider: { collectionView, indexPath, item in
collectionView.dequeueConfiguredReusableCell(
using: cellRegistration,
for: indexPath,
item: item
)
}
)
}
}

Upon running the application in a simulator, you’d get the following output:

Conclusion

To sum up:

  • iOS 14 introduced a new CellRegistration technique that doesn’t require registration using cell identifiers.

  • A new configuration API encapsulates the cell’s content and background view properties. UICollectionViewListCell provides us with a default configuration that can be set and updated based on states.

  • Customizations such as swipe actions and setting accessories can now be done directly when setting the cell configuration, thereby encouraging us to keep a single source of truth.

  • The new lists for UICollectionView are a UITableView lookalike and can be composed easily by specifying the layout and configuration (it can be on a per-section basis too) with appropriate header and footers.

We managed to quickly combine the things we’ve learned to build a simple UICollectionView in a declarative form. It’s time to say goodbye to cell item identifiers.

In the next article, we’ll look at what’s new in Diffable Data Sources for iOS 14. Stay tuned and thanks for reading.

Looking to get started with iOS 14? I recommend Programming iOS 14: Dive Deep into Views, View Controllers, and Frameworks, Eleventh Edition (Grayscale Indian Edition)