Swift
UITableView
Custom Cells
iOS Development
Programming

UITableview with more than One Custom Cells with Swift

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

Introduction

Using more than one custom cell type in a UITableView is normal once the screen shows mixed content such as text rows, image rows, or action rows. The key is to make cell selection data-driven instead of scattering if indexPath.row == ... logic throughout the controller.

Model the Rows First

The cleanest approach is to define a row model that describes which cell type belongs at each position. An enum works well for this.

swift
1import UIKit
2
3enum RowItem {
4    case title(String)
5    case photo(name: String, imageName: String)
6}

Once the data source uses RowItem, the table view can switch on the row type and dequeue the matching cell class. That is much easier to maintain than hardcoding cell decisions by row number alone.

Create One Subclass per Cell Type

Each custom cell should own only the outlets and configuration logic for its own layout.

swift
1import UIKit
2
3final class TitleCell: UITableViewCell {
4    @IBOutlet private weak var titleLabel: UILabel!
5
6    func configure(text: String) {
7        titleLabel.text = text
8    }
9}
swift
1import UIKit
2
3final class PhotoCell: UITableViewCell {
4    @IBOutlet private weak var nameLabel: UILabel!
5    @IBOutlet private weak var photoImageView: UIImageView!
6
7    func configure(name: String, imageName: String) {
8        nameLabel.text = name
9        photoImageView.image = UIImage(named: imageName)
10    }
11}

You can register these cells with nibs, storyboard prototypes, or direct class registration depending on how the screen is built.

Register and Dequeue by Identifier

The controller should register both cell types and then choose one in cellForRowAt.

swift
1import UIKit
2
3final class MixedCellsViewController: UIViewController, UITableViewDataSource {
4    @IBOutlet private weak var tableView: UITableView!
5
6    private let items: [RowItem] = [
7        .title("Today"),
8        .photo(name: "Ada", imageName: "avatar_ada"),
9        .title("Tomorrow"),
10        .photo(name: "Grace", imageName: "avatar_grace")
11    ]
12
13    override func viewDidLoad() {
14        super.viewDidLoad()
15        tableView.dataSource = self
16        tableView.register(UINib(nibName: "TitleCell", bundle: nil), forCellReuseIdentifier: "TitleCell")
17        tableView.register(UINib(nibName: "PhotoCell", bundle: nil), forCellReuseIdentifier: "PhotoCell")
18    }
19
20    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
21        items.count
22    }
23
24    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
25        switch items[indexPath.row] {
26        case .title(let text):
27            let cell = tableView.dequeueReusableCell(withIdentifier: "TitleCell", for: indexPath) as! TitleCell
28            cell.configure(text: text)
29            return cell
30
31        case .photo(let name, let imageName):
32            let cell = tableView.dequeueReusableCell(withIdentifier: "PhotoCell", for: indexPath) as! PhotoCell
33            cell.configure(name: name, imageName: imageName)
34            return cell
35        }
36    }
37}

This is the core pattern. The table view does not care that there are multiple custom cells; it only needs the right registration and dequeue logic.

Row Height and Layout

If the cells have different heights, use Auto Layout and enable self-sizing cells, or implement heightForRowAt if the heights are fixed.

For self-sizing:

swift
1override func viewDidLoad() {
2    super.viewDidLoad()
3    tableView.rowHeight = UITableView.automaticDimension
4    tableView.estimatedRowHeight = 80
5}

Self-sizing works best when each cell's constraints fully describe its height. If constraints are incomplete, mixed cell types often expose the layout problem quickly.

Multiple Sections Are Still an Option

Sometimes a second cell type is really a second section, not a second row style. If the data has a natural grouping, use sections instead of forcing all variation into one flat row list.

That said, when the content is interleaved in one feed, an enum-based row model remains the simplest design.

Avoid Controller-Centric Configuration

A common mistake is putting all label text and image logic directly in cellForRowAt. That makes the controller grow into a formatting object.

Keep the controller responsible for:

  • choosing the cell type
  • passing model data into the cell

Keep the cell responsible for:

  • outlet ownership
  • applying fonts, colors, and image content

That split becomes more valuable as the table adds a third or fourth custom cell type.

Common Pitfalls

The most common mistake is registering one identifier and trying to cast it to multiple cell classes. Each cell type needs its own reuse identifier.

Another mistake is letting reuse artifacts leak between cells. A reused cell may still show stale content if configure does not fully update every visible field.

Developers also overuse indexPath.row checks instead of modeling the row type in data. That approach works briefly and becomes fragile as soon as rows are inserted or reordered.

Finally, mixed cell heights often expose broken Auto Layout constraints. If one cell type renders incorrectly, inspect the cell's internal constraints before blaming the table view.

Summary

  • A UITableView can support multiple custom cell types without special framework tricks.
  • Model row types explicitly, usually with an enum or view model.
  • Register one reuse identifier per custom cell class or nib.
  • Dequeue the correct cell in cellForRowAt by switching on the row model.
  • Keep cell-specific layout and display logic inside the cell subclass, not in the controller.

Related reading
Free course
Beginner
7 lessons
2 hours
Tackling System Design Interview Problems

A short course that equips you with the skills to approach system design interviews methodically.

Start the free course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

All Rights Reserved.