1

Table view cell in cellForRowAt alway has all properties set to nil

import UIKit

class TodoTableViewCell: UITableViewCell {
    @IBOutlet weak var label: UILabel!
}

class TodosViewController: UITableViewController {

    @IBOutlet var TodosTableView: UITableView!
    var projects = [Project]()
    var todos = [Todo]()

    override func viewDidLoad() {
        super.viewDidLoad()
        TodosTableView.delegate = self
        self.tableView.register(TodoTableViewCell.self, forCellReuseIdentifier: "TodoTableViewCell1")
        // data init
    }

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cellIdentifier = "TodoTableViewCell1"
        var todo = projects[indexPath.section].todos[indexPath.row]
        guard let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath) as? TodoTableViewCell else {
            fatalError("The dequeued cell is not an instance of MealTableViewCell.")
        }

        cell.label?.text = todo.text // cell.label is always nil
        return cell
    }
}

outlet class

identifier identifier

It seems like identical issue Custom table view cell: IBOutlet label is nil

What I tried to do: - restart Xcode - recreate outlet - clean project - recreate view cell from scratch like here https://www.ralfebert.de/ios-examples/uikit/uitableviewcontroller/custom-cells/

Please help, iOS development drives me nuts already.

Alexander Kozachenko
  • 885
  • 2
  • 13
  • 26
  • 2
    BTW: `UITableViewController` has a [property for the table view](https://developer.apple.com/documentation/uikit/uitableviewcontroller/1614753-tableview) already. – clemens Feb 09 '18 at 15:07

4 Answers4

4

You don't need to register the class in the tableview if you're using prototype cells in Interface Builder. Try removing the registration function from viewDidLoad. Incidentally you can also set dataSource and delegate in IB - much neater code-wise.

Ash
  • 9,064
  • 3
  • 48
  • 59
  • intresting that I tried it before, but got error like this https://stackoverflow.com/questions/23526756/unable-to-dequeue-a-cell-with-identifier-cell-must-register-a-nib-or-a-class-f don't know what changed since – Alexander Kozachenko Feb 09 '18 at 15:14
  • Well, I did notice you've put your cell ID into both the Cell Identifier field and the accessibility identifier field - easily done, they're both called 'identifier' they're just in different sections. Maybe you initially had it in the wrong one? – Ash Feb 09 '18 at 15:16
  • 1
    perhaps so, I did not tested it. All those fields are very confusing after Android dev. thanks again. @Ash – Alexander Kozachenko Feb 09 '18 at 15:18
2

You are using the UITableView instance method:

func register(AnyClass?, forCellReuseIdentifier: String)

This only works if your custom UITableViewCell subclass is not setup using Interface Builder

If you've created your subclass using an xib. You should use:

func register(UINib?, forCellReuseIdentifier: String)

like:

let nib = UINib(nibName: "\(TodoTableViewCell.self)", bundle: nil)
self.tableView.register(nib, forCellReuseIdentifier: "TodoTableViewCell1")

If you're using prototype cells in a storyboard you don't need to register your cells at all.

beyowulf
  • 15,101
  • 2
  • 34
  • 40
  • thank you for reply. I used it because got error like this https://stackoverflow.com/questions/23526756/unable-to-dequeue-a-cell-with-identifier-cell-must-register-a-nib-or-a-class-f but somehow it doesn't appear now, everything works – Alexander Kozachenko Feb 09 '18 at 15:16
0

I think the identifier of the cell should be in the identifier from the attributes inspector column not the Identity inspector and in module in Identity inspector add your project

Vasilis D.
  • 1,416
  • 13
  • 21
0

Important note: One issue I haven't seen discussed is that if you use prototype cells in the storyboard, then explicitly registering the cell will make your outlets nil! If you explicitly register the cell then you are registering it without the storyboard which has your iboutlets. This will mean you defined your outlets in your cell but they aren't connected. Deleting the explicit registration will solve the issue.

Doesn't work:

tableVIew.register(MenuCell.self, forCellReuseIdentifier: "MenuCell")

Works:

// tableVIew.register(MenuCell.self, forCellReuseIdentifier: "MenuCell")
ScottyBlades
  • 12,189
  • 5
  • 77
  • 85