When programmatically adding a lazily instantiated text field to my viewcontroller, I only got it to work when calling view.addSubview(field)
twice, in the initiation of the textview, and in viewDidLoad()
. Removing the one in the initializer causes a crash, and removing the one in viewDidLoad()
doesn't let the text field appear.
class VC: UIViewController {
override func viewDidLoad() {
view.addSubview(textField)
view.setNeedsUpdatedConstraints)
}
lazy var textField: UITextField! = {
let field = UITextField()
field.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(field)
field.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
field.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
field.widthAnchor.constraint(equalTo: view.widthAnchor, multiplier: 0.8).isActive = true
field.heightAnchor.constraint(equalTo: view.heightAnchor, multiplier: 0.1).isActive = true
return field
} ()
}
Removing the view.addSubview(textField)
in viewDidLoad()
does not cause an error, but nothing shows up. Removing the view.addSubview(field)
in the initializer causes a crash with the following error: Unable to activate constraint with anchors <NSLayoutXAxisAnchor:0x600000469380 "UITextField:0x7fc931023600.centerX"> and <NSLayoutXAxisAnchor:0x600000469480 "UIView:0x7fc92f60c690.centerX"> because they have no common ancestor. Does the constraint or its anchors reference items in different view hierarchies? That's illegal.
Why are both calls necessary? Does this cause problems? What would be a better way of doing this? Thanks.
You need to add the text field as a subview in the textField
initializer because of the constraints. You can't setup the constraints until the view has been added.
You seem to need the call to add the text field in viewDidLoad
because without it, the lazy initializer is never called. So you don't actually need to call addSubview(textField)
. You just need any reference to textField
to trigger the initializer.
Unrelated but there is no reason for textField
to be declared as implicitly unwrapped.