2

I have got a fatal error: unexpectedly found nil while unwrapping an Optional value for an IBOutlet.

In my custom view, I have associated my outlet with a XIB file. I have double checked this. This is how it looks like:

@IBOutlet weak var label: UILabel! {
    didSet {
        label.textColor = .redColor()
    }
}

My implementation of layoutSubviews looks like:

override func layoutSubviews() {
    super.layoutSubviews()

    label.preferredMaxLayoutWidth = label.frame.size.width
}

Despite the fact, that layoutSubviews method has to be called after UI elements initialisation, I get an error:

fatal error: unexpectedly found nil while unwrapping an Optional value

This error is triggered by line:

label.preferredMaxLayoutWidth = label.frame.size.width

Why is that so? How to fix it?

Daumantas Versockas
  • 797
  • 1
  • 10
  • 29

3 Answers3

1

You can prevent the crash from happening by safely unwrapping label with an if let statement.

if let mylabel = label {
   mylabel.preferredMaxLayoutWidth = mylabel.frame.size.width
}
Forge
  • 6,538
  • 6
  • 44
  • 64
Nyakiba
  • 862
  • 8
  • 18
  • Yes, but for me it is interesting, why label is not ready? Also, where is the guarantee, that `preferredMaxLayoutWidth` will be setup? – Daumantas Versockas Nov 03 '16 at 09:32
  • read this: http://stackoverflow.com/questions/7588066/loading-custom-uiview-from-nib-all-subviews-contained-in-nib-are-nil – iGenio Nov 18 '16 at 11:23
1

You should use:

label?.preferredMaxLayoutWidth = label.frame.size.width

This before in an early call of layoutSubviews the outlet could not be yet setted, but in the next call will be. Using otional chaining you can avoid explicit optional unwrapping. if label is nil the assignment is skipped automatically.

iGenio
  • 398
  • 1
  • 8
0

Try doing it in viewDidLayoutSubviews instead of layoutSubviews. You UI elements should be ready in viewDidLayoutSubviews, but not necessary in layoutSubviews.

dirtydanee
  • 6,081
  • 2
  • 27
  • 43