Table & Collection Views
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.