Modernizing iOS Lists: From UITableView to UICollectionViewCompositionalLayout

Emre Degirmenci,SwiftUILayoutTableView

In the world of iOS development, UITableView has long been the go-to solution for displaying lists of data. However, with the introduction of UICollectionViewCompositionalLayout in iOS 13, developers now have a more flexible and powerful alternative. This post will guide you through the process of replacing UITableView with UICollectionViewCompositionalLayout, compare the two approaches, and explore some real-world scenarios where this transition makes sense. The Transition Process

The first step is to replace your existing UITableView with a UICollectionView. This involves updating your view hierarchy and adjusting any constraints or layout code.

// Before
let tableView = UITableView(frame: .zero, style: .plain)
 
// After
let collectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout())

Next, create a compositional layout that mimics the structure of your table view. For a simple list, this might look like:

func createLayout() -> UICollectionViewLayout {
    let itemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0),
                                          heightDimension: .estimated(44))
    let item = NSCollectionLayoutItem(layoutSize: itemSize)
    
    let groupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0),
                                           heightDimension: .estimated(44))
    let group = NSCollectionLayoutGroup.horizontal(layoutSize: groupSize, subitems: [item])
    
    let section = NSCollectionLayoutSection(group: group)
    
    return UICollectionViewCompositionalLayout(section: section)
}
 
collectionView.setCollectionViewLayout(createLayout(), animated: false)

With iOS 13, you can use the new UICollectionViewDiffableDataSource to manage your data:

tpealias DataSource = UICollectionViewDiffableDataSource<Section, Item>
var dataSource: DataSource!
 
func configureDataSource() {
    let cellRegistration = UICollectionView.CellRegistration<UICollectionViewListCell, Item> { cell, indexPath, item in
        var contentConfiguration = cell.defaultContentConfiguration()
        contentConfiguration.text = item.title
        cell.contentConfiguration = contentConfiguration
    }
    
    dataSource = DataSource(collectionView: collectionView) { collectionView, indexPath, item in
        return collectionView.dequeueConfiguredReusableCell(using: cellRegistration, for: indexPath, item: item)
    }
}

Replace your UITableViewDelegate methods with their UICollectionViewDelegate equivalents:

// Before
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
 
// After
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath)

Pros of UICollectionViewCompositionalLayout

Cons of UICollectionViewCompositionalLayout

Conclusion While UITableView remains a solid choice for simple lists, UICollectionViewCompositionalLayout offers a more powerful and flexible solution for modern iOS apps. By embracing this new approach, developers can create more dynamic and responsive user interfaces that adapt to changing content and user needs. As you embark on this transition, remember that the initial investment in learning and implementation will pay off in the long run with more maintainable and versatile code.

See you on the next one!

Sources:

Apple Developer doc. (opens in a new tab)

Sign up for my newsletter