Why are table view cells not showing in table view?

I am using more than one table view cell class on a table view. I have registered the reuse identifiers and the xibs. For some reason the cells are not showing. What should I check. I'm stumped.


Here is my code:


import UIKit
class DetailTableViewController: UITableViewController {
    let items = [0, 1]

    override func viewDidLoad() {
        super.viewDidLoad()

        tableView.register(DueDateSwitchTableViewCell.self, forCellReuseIdentifier: "DueDateSwitchTableViewCell")
     
        let xibDueDateSwitchTableViewCell = UINib(nibName: "DueDateSwitchTableViewCell", bundle: Bundle.main)
     
        tableView.register(xibDueDateSwitchTableViewCell, forCellReuseIdentifier: "DueDateSwitchTableViewCell")
        tableView.register(DueDatePickerTableViewCell.self, forCellReuseIdentifier: "DueDatePickerTableViewCell")
     
        let xibDueDatePickerTableViewCell = UINib(nibName: "DueDatePickerTableViewCell", bundle: Bundle.main)
     
        tableView.register(xibDueDatePickerTableViewCell, forCellReuseIdentifier: "DueDatePickerTableViewCell")
     
    }

    override func numberOfSections(in tableView: UITableView) -> Int {
      
        return 1
    }
    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
      
        return items.count
    }
    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
     
        print("tableView(_:cellForRowAt:)", "indexPath.row=", indexPath.row)
     
        let cell = UITableViewCell()
     
        switch indexPath.row {
         
        case 0:
         
            print("\tcase 0")
         
            let cell = tableView.dequeueReusableCell(withIdentifier: "DueDateSwitchTableViewCell", for: indexPath) as! DueDateSwitchTableViewCell
         
            cell.backgroundColor = UIColor.yellow
         
        case 1:
         
            print("\tcase 1")
         
            let cell = tableView.dequeueReusableCell(withIdentifier: "DueDatePickerTableViewCell", for: indexPath) as! DueDatePickerTableViewCell
         
            cell.datePicker.date = Date()
         
        default:
         
            break
         
        }
     
        return cell
     
    }

}


The cells show the numbers when I use this code in tableView(_:cellForRowAt:) before the line that says "return cell":


        cell.textLabel!.text = String(items[indexPath.section].hashValue)
Answered by ShinehahGnolaum in 280184022

I figured it out. I was returning the wrong table view cell.

Well, you're Doing It Wrong™. There are 3 separate mechanisms for using custom cell classes, and you can only use 1 of them.


1. In the normal (and, I'd say, preferred) case, you create prototype cells in the UITableView within IB. Note that you can have multiple cell types in one table view, which is your main requirement here. The cells do not all have to be of the same class — you can use the Identity inspector in IB to choose the desired custom subclass for each prototype. Each different prototype must have a different re-use identifier. (They don't have to have different classes, although they might.)


In this case, you do not need to register anything with the table view — your in-table-view prototypes are registered and handled automatically for you. You do, however, need to set a cell reuse identifier via the Attributes inspector in IB.


2. Or, you can define a single prototype cell in a separate NIB file. Again, you would use the Identity inspector to set a custom subclass, if that's what you want.


In this case, you must register the NIB programatically, similar to the code in lines 10-12 in your code fragment.


3. Or, you can register a cell view subclass that the table view will instantiate directly when needed (without using a NIB, or getting a prototype from a storyboard). This is similar to line 8 in your code fragment.


The important thing to know is that you must do only one of these three things for each cell reuse identifier. If you do 2 or more, as in the above code, your table view won't work.


In addition, you must implement the correct initializer, if your cell view subclass has explicit initialization code. (If it does not need any subclass-specific initialization, you can just let it inherit initializers from UITableViewCell.) For cases (1) and (2), your custom cells will be unarchived, so initialization must be in the "init?(coder:)" method. For case (3), your custom cells will be initialized via "init(style:reuseIdentifier:)".

I just tried using method number one that you listed above. I placed two table view cell objects in the table view in interface builder. I set them to the correct subclasses of UITableViewCell. I set the reuse identifiers. I commented out the lines of code in viewDidLoad() that registered the table view cells and their xib files. I'm getting the same result.

Accepted Answer

I figured it out. I was returning the wrong table view cell.

Why are table view cells not showing in table view?
 
 
Q