So here's the thing, I'm declaring a property like this:
var aNameLabel: UILabel {
guard let foo = Applicant.sharedInstance.realName else {
return UILabel(text: "获取姓名失败", color: .whiteColor())
}
return UILabel(text: foo, color: .whiteColor())
}
someView.addSubView(aNameLabel)
No common superview between views
let aNameLabel = UILabel(text: "Allen", color: .whiteColor())
var aNameLabel: UILabel = {
guard let foo = Applicant.sharedInstance.realName else {
return UILabel(text: "BAD", color: .whiteColor())
}
return UILabel(text: foo, color: .whiteColor())
}()
aNameLabel
guard let
The problem is that you are creating a new UILabel
every time you access the aNameLabel
variable (a computed property function runs every time you access it). Presumably you are doing the same thing for the superview of this view (when you access someView
in someView.addSubview()
in your example above). If so, that's why there's no common superview and you are crashing.
You should create only one instance of each UIView
used by your view controller, so creating a variable as a constant as you've shown is a great approach, or you can use a closure-initializer pattern like so:
var aNameLabel: UILabel = {
return UILabel(...)
}()
Notice in the above example the parentheses after the closing brace. Because it's a closure-initializer it will only be called once just like a let
constant.
Often a UIView
created with let
isn't appropriate because constant properties need to be initialized before init()
returns, and if you're creating views in a view controller you won't have a chance to add views until loadView()
is called. In this case, declare your UIView
s as implicitly-unwrapped optionals. They will be set to nil
by init()
which meets the initialization requirement, then you can set them to actual views later when viewDidLoad()
is called, for example:
class MyViewController: UIViewController {
var someSubview: UIView!
override func viewDidLoad() {
super.viewDidLoad()
someSubview = UIView()
view.addSubview(someSubview)
// now set constraints with SnapKit
}
}