I have a UIScrollView that contains a UIStackView, and I add views to it and if the UIStackView needs more space than the screen has then it will scroll thanks to the UIScrollView.
I am able to set constant heights on the views, but I also need to set a specific width on them, so that they have a specific width and are also centered in the stack view.
Something like this, except the widthAnchor does not work.
import UIKit
class ViewController: UIViewController {
let scrollView: UIScrollView = {
let sv = UIScrollView()
sv.translatesAutoresizingMaskIntoConstraints = false
sv.backgroundColor = .gray
return sv
}()
let stackView: UIStackView = {
let sv = UIStackView()
sv.translatesAutoresizingMaskIntoConstraints = false
sv.axis = .vertical
return sv
}()
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(scrollView)
scrollView.leftAnchor.constraint(equalTo: view.leftAnchor).isActive = true
scrollView.rightAnchor.constraint(equalTo: view.rightAnchor).isActive = true
scrollView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
scrollView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
scrollView.addSubview(stackView)
stackView.leftAnchor.constraint(equalTo: scrollView.leftAnchor).isActive = true
stackView.rightAnchor.constraint(equalTo: scrollView.rightAnchor).isActive = true
stackView.topAnchor.constraint(equalTo: scrollView.topAnchor).isActive = true
stackView.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor).isActive = true
stackView.widthAnchor.constraint(equalTo: scrollView.widthAnchor).isActive = true
let view1 = UIView()
view1.backgroundColor = .red
let view2 = UIView()
view2.backgroundColor = .blue
let view3 = UIView()
view3.backgroundColor = .green
let view4 = UIView()
view4.backgroundColor = .purple
stackView.addArrangedSubview(view1)
stackView.addArrangedSubview(view2)
stackView.addArrangedSubview(view3)
stackView.addArrangedSubview(view4)
view1.heightAnchor.constraint(equalToConstant: 200).isActive = true
view2.heightAnchor.constraint(equalToConstant: 300).isActive = true
view3.heightAnchor.constraint(equalToConstant: 420).isActive = true
view4.heightAnchor.constraint(equalToConstant: 100).isActive = true
// This does not work.
// view1.widthAnchor.constraint(equalToConstant: 40).isActive = true
}
}
The alignment
property on a UIStackView determines how its layout works perpendicular to its axis. By default, a UIStackView has an alignment of fill
. In constraint terms, fill
is like adding a constraint to (in this case) the left and right edges of the stack view for each arranged subview. These implicit constraints are likely causing your problem. Solution: set stackView.alignment =
either leading
, center
, or trailing
depending on your desired effect.
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