RodolfoAntonici
RodolfoAntonici

Reputation: 1625

UITableViewCell subclass IBOutlets returns nil

I've set up an UITableViewCell subclass from storyboard and connected the subviews as IBOutlets, as you can check here:

public class WaitingStatusTableViewCell: UITableViewCell {

@IBOutlet weak var leftBoxView: UIView!
@IBOutlet weak var leftTimeLabel: UILabel!
@IBOutlet weak var leftTitleLabel: UILabel!

Overrided the initialisers:

 override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
    super.init(style: style, reuseIdentifier: reuseIdentifier)
    self.initialConfigure()
}

required public init(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)
    self.initialConfigure()
}

And on the initialConfigure function I try to configure some properties of my subviews

    func initialConfigure() {
    self.leftBoxView.backgroundColor = UIColor.clearColor()
    self.leftBoxView.layer.shadowColor = UIColor.darkGrayColor().CGColor
    self.leftBoxView.layer.shadowPath = UIBezierPath(roundedRect: bounds, cornerRadius: 12.0).CGPath
    self.leftBoxView.layer.shadowOffset = CGSize(width: 2.0, height: 2.0)
    self.leftBoxView.layer.shadowOpacity = 1.0
    self.leftBoxView.layer.shadowRadius = 2
    self.leftBoxView.layer.masksToBounds = true
    self.leftBoxView.clipsToBounds = false
}

It doesn't work at all, I receive the following error:

fatal error: unexpectedly found nil while unwrapping an Optional value

Any ideas?

Oh, by the way, it works on drawsRect function, but I really want to understand the "why"

Upvotes: 2

Views: 1324

Answers (1)

jperl
jperl

Reputation: 1106

It all comes down to the order of execution:

Here are key moments that occur in sequence when the view is loaded:

  • init() is called on your table view subclass and an instance of the class is created. At this time all IBOutlets are nil. That's why you're getting this error.
  • Other subviews of the scene are initialized, IBOutlets are linked up and assigned values, and your instance is added to view hierarchy.
  • awakeFromNib() is then called, at which point your IBOutlets will no longer be have nil value so long as they have been properly linked through a storyboard.
  • drawRect() is called last, when the view is ready to be drawn to the screen

So, the solution is to move self.initialConfigure() into the awakeFromNib method:

override func awakeFromNib() {
    super.awakeFromNib()
    self.initialConfigure()
}

And trust that iOS will work its magic.

Here is an excellent article detailing the sequence of events that occur when a view is created, if you want to know more on the subject.

Upvotes: 7

Related Questions