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

Having to add subview to view controller twice with lazily instantiated UI views

当以编程方式将延迟实例化的文本字段添加到我的 viewcontroller 时,我只在调用 view.addSubview(field) 两次时,在文本视图的启动和 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
     } ()
}

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

为什么这两个调用都是必要的?这会导致问题吗?这样做的更好方法是什么?谢谢。

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

您似乎需要调用以在 viewDidLoad 中添加文本字段,因为没有它,惰性初始化程序永远不会被调用。所以你实际上不需要调用 addSubview(textField)。您只需要引用 textField 即可触发初始化程序。

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