Search code examples
iosswiftuiviewcontrollernslayoutconstraint

Why can I not constrain a view created in the viewDidLoad method to the ViewControllers View?


The following is an error message I get after I init a UIView in my ViewController and then constrain it to the main view of the ViewController.

Unable to activate constraint with anchors because they have no common ancestor. Does the constraint or its anchors reference items in different view hierarchies? That's illegal.

enter image description here

If you look at the picture I have provided you will see that in the storyboard I can just drop another UIView in the main view and then I can constrain it to the edges of the main view. This works perfectly fine, but I want to know how I can do the same thing in code. Just using NSLayoutConstraint and pin it to the top, bottom, leading, and trailing doesn't seem to be working for me. Any insight on this would be great.

    let webView: WKWebView = WKWebView()

    override func viewDidLoad() {
        super.viewDidLoad()

        webView.translatesAutoresizingMaskIntoConstraints = false

        NSLayoutConstraint(item: webView,
                       attribute: .leading,
                       relatedBy: .equal,
                       toItem: view,
                       attribute: .leading,
                       multiplier: 1.0,
                       constant: 0.0).isActive = true

        NSLayoutConstraint(item: webView,
                       attribute: .trailing,
                       relatedBy: .equal,
                       toItem: view,
                       attribute: .trailing,
                       multiplier: 1.0,
                       constant: 0.0).isActive = true

        NSLayoutConstraint(item: webView,
                       attribute: .top,
                       relatedBy: .equal,
                       toItem: view,
                       attribute: .top,
                       multiplier: 1.0,
                       constant: 0.0).isActive = true

        NSLayoutConstraint(item: webView,
                       attribute: .bottom,
                       relatedBy: .equal,
                       toItem: view,
                       attribute: .bottom,
                       multiplier: 1.0,
                       constant: 0.0).isActive = true

        let url = NSURL (string: someURL);
        let requestObj = NSURLRequest(url: url! as URL);
        webView.load(requestObj as URLRequest);
    }

Solution

  • It seems you forgot to add the webView to view before adding constraints:

    view.addSubview(webView)
    

    The final code:

    webView.translatesAutoresizingMaskIntoConstraints = false
    view.addSubview(webView)
    
    NSLayoutConstraint(item: webView,
                       attribute: .leading,
                       relatedBy: .equal,
                       toItem: view,
                       attribute: .leading,
                       multiplier: 1.0,
                       constant: 0.0).isActive = true
    
    NSLayoutConstraint(item: webView,
                       attribute: .trailing,
                       relatedBy: .equal,
                       toItem: view,
                       attribute: .trailing,
                       multiplier: 1.0,
                       constant: 0.0).isActive = true
    
    NSLayoutConstraint(item: webView,
                       attribute: .top,
                       relatedBy: .equal,
                       toItem: view,
                       attribute: .top,
                       multiplier: 1.0,
                       constant: 0.0).isActive = true
    
    NSLayoutConstraint(item: webView,
                       attribute: .bottom,
                       relatedBy: .equal,
                       toItem: view,
                       attribute: .bottom,
                       multiplier: 1.0,
                       constant: 0.0).isActive = true
    
    let url = NSURL (string: "");
    let requestObj = NSURLRequest(url: url! as URL);
    webView.load(requestObj as URLRequest);