8
votes

I have a custom UITableViewCell subclass with a simple IBOutlet setup for a UILabel.

class SegmentCell: UITableViewCell {

    @IBOutlet weak var test: UILabel!

    override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
        test.text = "Some Text"
    }

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

}

Convinced I have everything set up correct have followed other answers, but the UILabel is always nil.

ViewController: viewDidLoad:

self.tableView.registerClass(SegmentCell.self, forCellReuseIdentifier: "Cell")

cellForForAtIndexPath

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCellWithIdentifier("Cell") as! SegmentCell
    return cell
}
  • Cell is set to Custom
  • Reuse identifier is correct
  • Cells class is SegmentCell
  • Tableview content is Dynamic Prototypes

What am I missing?

6
You don't need call self.tableView.registerClass(SegmentCell.self, forCellReuseIdentifier: "Cell") on viewDidLoad, just set the prototypeCells class to "SegmentCell" on Mainstoryboard. - Fernando Mondo
I realise this is a really old question, but it currently has no answer and I happened upon it because I'm encountering a similar problem. In your case, I think the weak var is the key - if your SegmentCell is the only thing that ever holds a reference to the UILabel, that won't contribute to the retain count and so the label will be deallocated because nobody has a strong reference to it. By the time you attempt to set .text, it's already gone. - Chris

6 Answers

3
votes

Based on the way you register your cell, it is not going to be loading it from a storyboard or xib file. It will be invoking that init method only. Your init method does not create the label, so it will always be nil.

You should also use dequeueReusableCellWithIdentifier(_:forIndexPath:) instead of dequeueReusableCellWithIdentifier(_:). The latter predates storyboards and will return nil unless you have previously created a cell with that identifier and returned it.

Lastly, the init method that the tableView is calling is not the one you've implemented, or the app would crash on test.text = ... while trying to unwrap a nil optional.

3
votes

Since You are uisg Xib file you have to register with ,

tableView.register(UINib(nibName: "yourNib", bundle: nil), forCellReuseIdentifier: "CellFromNib")

Think, if only register with class ,system will not know the its Xib.This work for me.

1
votes

UITableViewCell class and ContentView class can't be same.

0
votes

You should register it first in the viewDidLoad function.

self.tableView.registerClass(CustomCell.self, forCellReuseIdentifier: "Cell")
0
votes

I have same issue, after add custom cell class to cell in tableview placed in Storyboard. I also register cell, like in documentation. But now I solve my issue.

"I remove registering and inspect cell again, all IBOutlets initialised"

0
votes

I think that basically the outlets are not setup yet at init time. If you want to get to the outlets and manipulate them, then override didMoveToSuperview or similar and do it in there. For instance, this is what I had to do to get to the button outlet in my cell:

open class MyTableViewCell: UITableViewCell {
    // Top stack view, not the inner one.
    @IBOutlet weak var stackView: UIStackView!
    @IBOutlet weak var buttonView: UIButton?

    open override func didMoveToSuperview() {
        buttonView?.titleLabel?.adjustsFontForContentSizeCategory = true
    }

    func adjustForAccessibilityCategory(accessible: Bool) {
        if accessible {
            stackView.axis = .vertical
            stackView.alignment = .leading
            stackView.spacing = 2
        } else {
            stackView.axis = .horizontal
            stackView.alignment = .center
            stackView.spacing = 20
        }
    }

    open override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
        if #available(iOS 11.0, *) {
            adjustForAccessibilityCategory(accessible: traitCollection.preferredContentSizeCategory.isAccessibilityCategory)
        }
    }
}