简体   繁体   中英

creating stackView inside of view controller crashes with 'Unable to activate constraint with anchors'

I am trying to create a very simple stackView in my viewcontroller. I want the stackView to cover the entire screen. How I am creating the stackView is

import UIKit
import Firebase

class Vc: UIViewController {
        
var scrollView: UIScrollView {
    let scroll = UIScrollView()
    scroll.isScrollEnabled = true
    return scroll
}

var stackView: UIStackView {
    let stack = UIStackView()
    stack.axis = .vertical
    stack.distribution = .fillEqually
    return stack
    
}
    

override func viewDidLoad() {
    super.viewDidLoad()
    navigationController?.navigationBar.tintColor = .white
    self.navigationItem.title = "Profile"
    self.view.backgroundColor = UIColor.white
    addStackViewAnchors()
    
}

func addStackViewAnchors() {
    view.addSubview(stackView)
    stackView.anchors(top: view.safeAreaLayoutGuide.topAnchor, topPad: 0, bottom: view.safeAreaLayoutGuide.bottomAnchor, bottomPad: 0, left: view.safeAreaLayoutGuide.leftAnchor, leftPad: 0, right: view.safeAreaLayoutGuide.rightAnchor, rightPad: 0, height: .zero, width: .zero)
}

}

When I run this, my app crashes and it says

Terminating app due to uncaught exception 'NSGenericException', reason: 'Unable to activate constraint with anchors <NSLayoutYAxisAnchor:0x283c5e840 "UIStackView:0x135666a90.top"> and <NSLayoutYAxisAnchor:0x283c5e140 "UILayoutGuide:0x28103b8e0'UIViewSafeAreaLayoutGuide'.top"> because they have no common ancestor.  Does the constraint or its anchors reference items in different view hierarchies?  That's illegal.'
 terminating with uncaught exception of type NSException

There are no conflicting constraints because the stackView is the only anchor being set.

Every time you called stackView here you init a new instance of Stack View from inside your function. That's the reason when you called stackView.anchor the error appears because it is autolayout the new instance of stackView not the stackView you add subview into your VC .

The thing you should do is create a variable to store your stackView instance so the stackView init for once and reuse in all in the VC .

Beside of that, we use leadingAnchor instead of leftAnchor ; trailingAnchor instead of rightAnchor .

Code will be like this

class ViewController: UIViewController {
    private var stackViewInScreen : UIStackView?
    
    var stackView: UIStackView {
        let stack = UIStackView()
        stack.axis = .vertical
        stack.distribution = .fillEqually
        return stack
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        self.view.backgroundColor = UIColor.white
        addStackViewAnchors()
    }

    func addStackViewAnchors() {
        self.stackViewInScreen = stackView
        self.view.addSubview(self.stackViewInScreen!)
        
        self.stackViewInScreen!.translatesAutoresizingMaskIntoConstraints = false
        self.stackViewInScreen?.backgroundColor = UIColor.orange
        NSLayoutConstraint.activate([
            self.stackViewInScreen!.topAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.topAnchor, constant: 0),
            self.stackViewInScreen!.leadingAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.leadingAnchor, constant: 0),
            self.stackViewInScreen!.trailingAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.trailingAnchor, constant: 0),
            self.stackViewInScreen!.bottomAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.bottomAnchor, constant: 0)
        ])
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM