lujop lujop - 8 days ago 6
iOS Question

Can UIStackView be constrained?

I have a

UIScrollView
that fills all the window and that contains a vertical
UIStackView
where I want to add
UILabels
that fill all available width.

The
UIStackView
is pinned to all the edges of
UIScrollView
, and I expect it to fill all the
UIScrollView
. But it seems that it completely ignores all the constriants and it only sizes to fit it's childs. Why that behaviour?

To illustrate that if I add labels that way:

scrollView.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|[stackView]|", options: NSLayoutFormatOptions.alignAllCenterX, metrics: nil, views: ["stackView": stackView]))
scrollView.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|[stackView]|", options: NSLayoutFormatOptions.alignAllCenterX, metrics: nil, views: ["stackView": stackView]))

for _ in 1 ... 20 {
let textLabel = UILabel()
textLabel.backgroundColor = UIColor.yellow
textLabel.text = "Hi World xxxx"
stackView.addArrangedSubview(textLabel)
textLabel.widthAnchor.constraint(equalTo: stackView.widthAnchor).isActive = true //Doesn't work as expected

}


what I get is this: (the cyan background is the
UIScrollView
and you can see that labels doesn't take all width due to that
UIStackView
contraints doesn't apply)

Result with stackview contraints

And only if I change the label contraint to use scrollView it works as desired:

textLabel.widthAnchor.constraint(equalTo: scrollView.widthAnchor).isActive = true


Then the result is as expected:
enter image description here

Why that behaviour? Someone can explain why the constraints on
UIStackView
doesn't work as I expect?

Complete source code avaiable at that gist

Answer

Everything is correct. Its just that you have not specified the width of the content view(the stack view). Add this line and thing will work perfectly.

scrollView.widthAnchor.constraint(equalTo: stackView.widthAnchor, multiplier: 1).isActive = true;

Note: Pinning scroll view's leading trailing with content view does, not provide the width to the content view. A separate width constraint is required, other wise the content view will have its width equal to its intrinsic width.

Comments