there is something strange with xcode. Suddenly the ordinary flow is broken. To check it I've created a new project with just two viewControllers. First (named ViewController) contains only one button to open the second (named NewViewController) controller, which contains the only UILabel.
import UIKit
class ViewController: UIViewController {
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "Show New View" {
guard let newVC = segue.destination as? NewViewController else { return }
newVC.passedText = "some abstract text"
}
}
}
import UIKit
class NewViewController: UIViewController {
@IBOutlet weak var myLabel: UILabel!
var passedText: String? {
didSet {
guard let text = passedText else { return }
myLabel.text = text
}
}
override func viewDidLoad() {
super.viewDidLoad()
}
}
But the debugger shows what the UILabel is nil
What I've made wrong?
No, nothing has "broken". You're the one who is doing it wrong. At the time you are calling newVC.passedText = "some abstract text"
, newVC
has not yet loaded its view and its outlets are still nil
. So the call to set myLabel.text
is happening at time when the outlet is indeed still nil
.
Your mistake is that you are trying to configure myLabel
too soon. Store the value in newVC
, yes. But as for setting myLabel.text
, wait until viewDidLoad
, when the view and outlets are working.
The correct pattern, therefore, looks like this:
var passedText: String? {
didSet {
guard let text = passedText else { return }
myLabel?.text = text
}
}
override func viewDidLoad() {
super.viewDidLoad()
guard let text = passedText else { return }
myLabel?.text = text
}
Now your code does the right thing regardless of when passedText
is set in relation to viewDidLoad
.