必须使用延迟实例化的UI视图将子视图添加到视图控制器两次

时间:2017-12-17 02:48:18

标签: ios swift uikit viewcontroller lazy-initialization

当以编程方式将一个懒惰的实例化文本字段添加到我的viewcontroller时,我只能在调用view.addSubview(field)两次,在textview的启动和viewDidLoad()中使用它。删除初始值设定项中的那个会导致崩溃,删除viewDidLoad()中的那个不会让文本字段出现。

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
     } ()
}

删除view.addSubview(textField)中的viewDidLoad()不会导致错误,但不会显示任何内容。删除初始化程序中的view.addSubview(field)会导致崩溃,并显示以下错误: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.

为什么两个电话都必要?这会导致问题吗?这会是一个更好的方法吗?感谢。

1 个答案:

答案 0 :(得分:0)

由于约束,您需要在textField初始值设定项中将文本字段添加为子视图。在添加视图之前,您无法设置约束。

您似乎需要调用viewDidLoad中添加文本字段,因为如果没有它,则永远不会调用延迟初始值设定项。因此,您实际上并不需要致电addSubview(textField)。您只需要textField的任何引用来触发初始值设定项。

不相关,但没有理由将textField声明为隐式展开。