Morgan Wilde
Morgan Wilde

Reputation: 17333

Custom TableView cell dequeue fatal error: unexpectedly found nil

The setup

I'm trying to customise a prototype cell. Here's the cell in my main storyboard.

enter image description here

I have a custom cell class.

class UserListTableViewCell: UITableViewCell {
    @IBOutlet weak var nameLabel: UILabel!
    @IBOutlet weak var dateCreatedLabel: UILabel!
    @IBOutlet weak var dateOfLastLoginLabel: UILabel!
}

It is linked up with the prototype cell in the same storyboard.

enter image description here

And just to be sure, here's the custom class name in the inspector.

enter image description here

Finally, in my view controller, I have the following extension that implements the UITableViewDataSource protocol.

extension UserListViewController: UITableViewDataSource {
    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return users.count
    }

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCellWithIdentifier("userListCell", forIndexPath: indexPath) as! UserListTableViewCell
        cell.nameLabel.text = users[indexPath.row].name
        return cell
    }
}

Along with the viewDidLoad method.

override func viewDidLoad() {
    super.viewDidLoad()
    tableView.dataSource = self
    tableView.tableHeaderView = tableHeaderView
    tableView.registerClass(UserListTableViewCell.self, forCellReuseIdentifier: "userListCell")
}

The problem

When I launch this in the simulator I get a runtime crash with fatal error: unexpectedly found nil while unwrapping an Optional value. In the stack trace all of my labels are nil.

What's going on here and how can I fix this?

Upvotes: 3

Views: 1381

Answers (1)

Martin R
Martin R

Reputation: 540075

Storyboard prototype cells are automatically registered to be used with dequeueReusableCellWithIdentifier(). If no cell is available for reuse, a new one will be instantiated from the prototype cell (using initWithCoder:), with all the labels and other elements that you defined in the Storyboard.

With

tableView.registerClass(UserListTableViewCell.self, forCellReuseIdentifier: "userListCell")

you replace the registration of the prototype cell. Now dequeueReusableCellWithIdentifier() will create an instance of UserListTableViewCell (using initWithStyle: as @dan said). But there is no connection to the prototype cell, so the labels and other elements are not created. In your case, cell.nameLabel is nil, and therefore accessing cell.nameLabel.text throws the exception.

Upvotes: 4

Related Questions