iOS
UITableView
Cell Identifier
Storyboard
Xcode

unable to dequeue a cell with identifier Cell - must register a nib or a class for the identifier or connect a prototype cell in a storyboard

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

This error means the table view or collection view was asked to dequeue a reusable cell with an identifier that has never been registered. UIKit knows the identifier string you asked for, but it does not know which cell class, nib, or storyboard prototype belongs to it. The fix is always the same in principle: make the reuse identifier and the registration source line up exactly.

Understand What dequeueReusableCell Expects

Reusable cells are part of UIKit’s reuse system. When you call dequeueReusableCell, UIKit looks up a registration entry for that reuse identifier. That entry can come from one of three places:

  • a prototype cell in a storyboard,
  • a class registered in code,
  • or a nib registered in code.

If none of those exist for the identifier, you get the dequeue error.

A correct programmatic setup looks like this.

swift
1import UIKit
2
3final class ViewController: UIViewController, UITableViewDataSource {
4    private let tableView = UITableView()
5    private let items = ["One", "Two", "Three"]
6
7    override func viewDidLoad() {
8        super.viewDidLoad()
9        tableView.frame = view.bounds
10        tableView.dataSource = self
11        tableView.register(UITableViewCell.self, forCellReuseIdentifier: "Cell")
12        view.addSubview(tableView)
13    }
14
15    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
16        items.count
17    }
18
19    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
20        let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
21        cell.textLabel?.text = items[indexPath.row]
22        return cell
23    }
24}

The important line is register. Without it, the dequeue call has no registered cell source.

Storyboard Projects Need a Matching Prototype Identifier

If you are using a storyboard prototype cell, you usually do not call register in code. Instead, you set the prototype cell’s Reuse Identifier in Interface Builder and make sure the string in code matches it exactly.

The failure mode is simple:

  • storyboard identifier is MyCell,
  • code asks for Cell,
  • UIKit cannot find a matching registration.

The same happens if the prototype cell is attached to a different table view than the one making the dequeue call.

When debugging storyboard setups, check these items first:

  • the correct scene is loaded,
  • the table view outlet is connected,
  • the prototype cell is inside that table view,
  • and the Reuse Identifier matches the dequeue string exactly.

Register a Nib for Custom Cell Layouts

If your cell is designed in a separate nib file, register the nib instead of only the class.

swift
1override func viewDidLoad() {
2    super.viewDidLoad()
3
4    let nib = UINib(nibName: "ProfileCell", bundle: nil)
5    tableView.register(nib, forCellReuseIdentifier: "ProfileCell")
6}

Then dequeue the same identifier.

swift
let cell = tableView.dequeueReusableCell(withIdentifier: "ProfileCell", for: indexPath)

This is the correct approach when the cell layout lives in a nib rather than being constructed entirely in code.

Custom Cell Classes Must Also Match

If you register a custom class, the dequeue identifier and the cast target must agree with the class you registered.

swift
1final class ProfileCell: UITableViewCell {
2    func configure(name: String) {
3        textLabel?.text = name
4    }
5}
6
7tableView.register(ProfileCell.self, forCellReuseIdentifier: "ProfileCell")
8
9let cell = tableView.dequeueReusableCell(withIdentifier: "ProfileCell", for: indexPath) as! ProfileCell
10cell.configure(name: "Ava")

A mismatched cast gives a different error, but it often appears in the same area of code, so it is worth checking while you are already fixing registration issues.

Collection Views Follow the Same Rule

The same root cause applies to UICollectionView. A collection view cell also has to be registered through a storyboard prototype, class, or nib before dequeueing.

swift
collectionView.register(UICollectionViewCell.self, forCellWithReuseIdentifier: "Cell")
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath)

So even if the original error mentions a table cell, the mental model is reusable across UIKit’s list views.

Common Pitfalls

  • Registering Cell in code but dequeuing cell or another differently cased string.
  • Using a storyboard prototype cell and also assuming a programmatic registration happened automatically.
  • Registering a class when the real layout lives in a nib file.
  • Connecting the prototype cell in one storyboard scene while a different table view instance is actually on screen.
  • Forgetting that collection views have the same registration requirement.

Summary

  • The dequeue error means UIKit has no registered cell source for that reuse identifier.
  • Fix it by using exactly one valid registration path: storyboard prototype, class, or nib.
  • Make the reuse identifier string match in Interface Builder and code.
  • Register nibs for nib-based custom cells and classes for fully programmatic cells.
  • Once registration and identifiers line up, dequeueReusableCell works predictably.

Course illustration
Course illustration

All Rights Reserved.