← All courses

Table & Collection Views

🗓 May 31, 2026 ⏱ 2 min read

Why these matter

Most app screens are essentially lists: a chat list, a feed, settings, search results. UIKit provides two highly optimised components for this: UITableView (vertical lists) and UICollectionView (grids and custom layouts). Both recycle their cells — only the visible rows exist in memory — so they stay fast even with thousands of items.

How a table view works

A table view doesn’t know your data; it asks a data source two questions through delegate methods: “how many rows?” and “what cell goes at this row?”. This is the delegate pattern in action.

class UsersViewController: UITableViewController {
    let users = ["Anand", "Priya", "Ravi"]

    override func tableView(_ tableView: UITableView,
                            numberOfRowsInSection section: Int) -> Int {
        users.count
    }

    override func tableView(_ tableView: UITableView,
                            cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
        var config = cell.defaultContentConfiguration()
        config.text = users[indexPath.row]
        cell.contentConfiguration = config
        return cell
    }

    override func tableView(_ tableView: UITableView,
                            didSelectRowAt indexPath: IndexPath) {
        print("Tapped \(users[indexPath.row])")
    }
}

Cell reuse — the key idea

dequeueReusableCell is what makes lists efficient: instead of creating a new cell for every row, the table view reuses cells that scrolled off-screen. If you created a fresh cell per row, a long list would be slow and memory-hungry. Always dequeue.

Collection views for grids

UICollectionView works the same way but supports flexible layouts — grids, horizontal carousels, custom arrangements. It’s what you’d use for a photo gallery.

The modern approach: diffable data sources

Newer iOS code uses diffable data sources and cell registrations. Instead of implementing delegate methods and calling reloadData(), you apply a “snapshot” of your data and UIKit animates exactly what changed — safer and smoother.

var snapshot = NSDiffableDataSourceSnapshot<Section, String>()
snapshot.appendSections([.main])
snapshot.appendItems(users)
dataSource.apply(snapshot, animatingDifferences: true)

Common mistakes

  • Not reusing cells (creating new ones each time) — causes lag.
  • Forgetting to register a cell identifier (crash on dequeue).
  • Calling reloadData() for tiny changes instead of using diffable snapshots.
Summary: Table and collection views power list-based UIs by recycling cells. Provide data through the data source (or a modern diffable data source), and always dequeue reusable cells for performance.