spoax
spoax

Reputation: 589

Tableview error when using custom cell class

I am trying to make a tableViewController with a custom cell class programmatically but I am getting this error:

Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'unable to dequeue a cell with identifier cellId - must register a nib or a class for the identifier or connect a prototype cell in a storyboard' *** First throw call stack:

I have several UItableViews in my app with custom cells and they all work fine but for some reason, this one isn't working. I've spent the last few hours trying to work it out but can't see the problem, can someone help me please?

This is my tableview class:

var tableView = UITableView()
    var twoDimensionalArray = [
        cameraInfoStruct(cameraInfo: ["Camera Body","Lens", "FPS", "Shutter Angle", "Colour Temperature", "Resolution Width", "Resolution Height", "Format", "Camera Rig"]),
        cameraInfoStruct(cameraInfo:["Focus Length", "F - Stop", "Camera Height", "Camera Tilt", "Camera Roll", "Filter"])
    ]

    let cellId = "cellId"
    let screenHeight = UIScreen.main.bounds.height
    let screenWidth = UIScreen.main.bounds.width
    let sectionHeaders = ["General", "Advanced"]

    override func viewDidLoad() {
        super.viewDidLoad()

        addTableView()
    }

    func addTableView() {
        tableView = UITableView(frame: CGRect(x: 0, y: 0, width: screenWidth, height: screenHeight))
        tableView.register(UITableViewCell.self, forCellReuseIdentifier: "MyCell")
        tableView.dataSource = self
        tableView.delegate = self
        tableView.tableFooterView = UIView()
        self.view.addSubview(tableView)
    }

    func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {

        if let sectionHeaderArray = sectionHeaders as? [String] {
            return sectionHeaderArray[section]
        }
        return "unknown"
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return twoDimensionalArray[section].cameraInfo.count
    }

    func numberOfSections(in tableView: UITableView) -> Int {
        return sectionHeaders.count
    }

    func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
        cell.backgroundColor = UIColor.white
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

        let cell = tableView.dequeueReusableCell(withIdentifier: cellId, for: indexPath) as! cameraInfoCell
        let shotNumber = twoDimensionalArray[indexPath.section].cameraInfo[indexPath.row]

        cell.textLabel?.text = shotNumber

        return cell
    }
}

And this is my custom cell class:

class cameraInfoCell: UITableViewCell {

    override func layoutSubviews() {
        super.layoutSubviews()

        self.textLabel?.frame.origin.x = 20
        self.detailTextLabel?.frame.origin.x = 20
        self.detailTextLabel?.textColor = UIColor(red:0.73, green:0.73, blue:0.73, alpha:1.0)
    }

    override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
        super.init(style: .subtitle, reuseIdentifier: reuseIdentifier)

    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

Upvotes: 0

Views: 119

Answers (2)

wottle
wottle

Reputation: 13619

You use two different cellIDs:

In your class, you define a cellId variable,

let cellId = "cellId"

which you use in cellForRowAt:

    let cell = tableView.dequeueReusableCell(withIdentifier: cellId, for: indexPath) as! cameraInfoCell

In addTableView, you use the hardcoded string "MyCell":

    tableView.register(UITableViewCell.self, forCellReuseIdentifier: "MyCell")

To fix it, use the cellId in both places, so change the code in your addTableView method to:

    tableView.register(cameraInfoCell.self, forCellReuseIdentifier: cellId)

Upvotes: 5

Shehata Gamal
Shehata Gamal

Reputation: 100503

You have to register the table inviewDidLoad either

 tableView.register(cellClassName.self, forCellReuseIdentifier: "cellId")

Upvotes: 1

Related Questions