XCode is throwing up the following constraint error when I attempt to use a UIStackView:
(
"<NSAutoresizingMaskLayoutConstraint:0x7f87a1dfa360 h=--& v=--& V:[UIStackView:0x7f87a6403a00(0)]>",
"<NSLayoutConstraint:0x7f87a6410590 'UISV-canvas-connection' UIStackView:0x7f87a6403a00.top == UIView:0x7f87a6409630.top>",
"<NSLayoutConstraint:0x7f87a6444170 'UISV-canvas-connection' V:[UIView:0x7f87a644d790]-(0)-| (Names: '|':UIStackView:0x7f87a6403a00 )>",
"<NSLayoutConstraint:0x7f87a645bec0 'UISV-fill-equally' UIView:0x7f87a6407a10.height == UIView:0x7f87a6409630.height>",
"<NSLayoutConstraint:0x7f87a6458f40 'UISV-fill-equally' UIView:0x7f87a644d790.height == UIView:0x7f87a6409630.height>",
"<NSLayoutConstraint:0x7f87a64306d0 'UISV-spacing' V:[UIView:0x7f87a6409630]-(5)-[UIView:0x7f87a6407a10]>",
"<NSLayoutConstraint:0x7f87a643bea0 'UISV-spacing' V:[UIView:0x7f87a6407a10]-(5)-[UIView:0x7f87a644d790]>"
)
Will attempt to recover by breaking constraint
<NSLayoutConstraint:0x7f87a643bea0 'UISV-spacing' V:[UIView:0x7f87a6407a10]-(5)-[UIView:0x7f87a644d790]>
My view controller is as follows:
public class ExampleController: UIViewController {
let v1 = UIView(frame: CGRect(x: 0, y: 0, width: 250, height: 100))
let v2 = UIView(frame: CGRect(x: 0, y: 0, width: 250, height: 300))
let v3 = UIView(frame: CGRect(x: 0, y: 0, width: 250, height: 200))
let parent1 = UIStackView()
public override func viewDidLoad() {
super.viewDidLoad()
v1.backgroundColor = .red
v2.backgroundColor = .green
v3.backgroundColor = .blue
parent1.axis = .vertical
parent1.distribution = .fillEqually
parent1.spacing = 5 // TODO: This causes the error!
parent1.addArrangedSubview(v1)
parent1.addArrangedSubview(v2)
parent1.addArrangedSubview(v3)
view.addSubview(parent1)
}
// MARK: Constraints
private var didUpdateConstraints = false
override public func updateViewConstraints() {
if !didUpdateConstraints {
parent1.snp.makeConstraints { (make) -> Void in
make.edges.equalToSuperview()
}
didUpdateConstraints = true
}
super.updateViewConstraints()
}
}
The distribution of the stack view doesn't seem to make a difference. Whenever spacing is set, I receive the error.
What is the conflict with my constraints?
What is UISV-canvas-connection?
It's actually not breaking because of the spacing. It's breaking because of the way you are creating the views :D
When you create a view like...
let v1 = UIView(frame: CGRect(x: 0, y: 0, width: 250, height: 100))
When the view gets laid out it gets a default set of constraints added to it. The same is true for the UIStackView.
When you create it like...
let parent1 = UIStackView()
It gets a frame of (0, 0, 0, 0) and then constraints added to it to keep that frame position and height.
The error you are getting is because of the height and width of the stack view.
<NSAutoresizingMaskLayoutConstraint:0x7f87a1dfa360 h=--& v=--& V:[UIStackView:0x7f87a6403a00(0)]>
This line is referring to those "automatic" constraints.
Your best option is to recreate the views widths and height using constraints.
Like this...
// using this format means you can create the view and add all the
// other config to it at the same time
let v1: UIView = {
let u = UIView()
// this line stops the "automatic" constraints being added
u.translatesAutoresizingMaskIntoConstraints = false
u.backgroundColor = .red
// now you have to add your own constraints though
u.heightAnchor.constraint(equalToConstant: 100).isActive = true
u.widthAnchor.constraint(equalToConstant: 250).isActive = true
return u
}()
let v2: UIView = {
let u = UIView()
u.translatesAutoresizingMaskIntoConstraints = false
u.backgroundColor = .green
u.heightAnchor.constraint(equalToConstant: 100).isActive = true
u.widthAnchor.constraint(equalToConstant: 250).isActive = true
return u
}()
let v3: UIView = {
let u = UIView()
u.translatesAutoresizingMaskIntoConstraints = false
u.backgroundColor = .blue
u.heightAnchor.constraint(equalToConstant: 100).isActive = true
u.widthAnchor.constraint(equalToConstant: 250).isActive = true
return u
}()
let parent1: UIStackView = {
let s = UIStackView()
s.translatesAutoresizingMaskIntoConstraints = false
s.spacing = 5
s.axis = .vertical
s.distirbution = .fillEqually
return s
}()
public override func viewDidLoad() {
super.viewDidLoad()
// I moved all the config stuff into the creation of each view...
// No need to have them here.
parent1.addArrangedSubview(v1)
parent1.addArrangedSubview(v2)
parent1.addArrangedSubview(v3)
view.addSubview(parent1)
}
You are using .fillEqually in the stack view. This will give each view heights equal to each other. This is going to conflict with the height constraint you added to them. Maybe you should remove the constraints from each view entirely and let the stack view do the layout.
Like this...
let v2: UIView = {
let u = UIView()
u.translatesAutoresizingMaskIntoConstraints = false
u.backgroundColor = .green
return u
}()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With