1

I want to set a UIStackView with 3 views to the bottom of my so that the centre view is positioned in the centre and the other views are adjusted accordingly, I want also to be able to set the width and height anchors for all 3 views. This is the desired outcome:

Outcome

This is what I'm getting:

Desired Outcome

This is the code I'm using:

bottomStackView = UIStackView(arrangedSubviews: [pickerView, downloadContentButton,  shareButton])
    bottomStackView.alignment = .center
    bottomStackView.distribution = .fill
    bottomStackView.axis = .horizontal
    bottomStackView.spacing = 5
    bottomStackView.translatesAutoresizingMaskIntoConstraints = false
    view.addSubview(bottomStackView)
    
    bottomStackView.anchor(top: nil, leading: view.leadingAnchor, bottom: view.safeAreaLayoutGuide.bottomAnchor, trailing: view.trailingAnchor)
    bottomStackView.heightAnchor.constraint(equalToConstant: 150).isActive = true
    bottomStackView.widthAnchor.constraint(equalTo: view.widthAnchor).isActive = true
    
    pickerView.heightAnchor.constraint(equalToConstant: 120).isActive = true
    shareButton.heightAnchor.constraint(equalToConstant: 150).isActive = true
    shareButton.widthAnchor.constraint(equalTo: pickerView.widthAnchor).isActive = true
    
    downloadContentButton.heightAnchor.constraint(equalToConstant: 30).isActive = true
    downloadContentButton.widthAnchor.constraint(equalToConstant: 30).isActive = true
    
    shareButton.widthAnchor.constraint(equalToConstant: 80).isActive = true
    shareButton.heightAnchor.constraint(equalToConstant: 80).isActive = true
General Grievance
  • 4,555
  • 31
  • 31
  • 45
StackGU
  • 868
  • 9
  • 22
  • If you are going to dictate absolutely the height and width of the views and the spacing between them, what is the purpose of the stack view? – matt Oct 02 '20 at 22:59
  • I wanted to implement it because of the change in screen size in different devices – StackGU Oct 02 '20 at 23:04
  • 2
    But if the sizes and spacing are absolute, what difference will screen size make? – matt Oct 03 '20 at 00:07
  • 2
    To put it another way: so suppose the screen size changes; what is it that should change about your views? Because, as you have it, nothing can and nothing will. – matt Oct 03 '20 at 00:16
  • Lets say I set my views [width:80]-30-[width:30]-30-[width:80], if the screen size changes the spacing between the views (in this case 30) needs to change. I wanted the stackView to calculate how much to space it – StackGU Oct 03 '20 at 00:23
  • Ok good answer, so what changes is the spacing. I’ll show you how to do that, hang on a bit. – matt Oct 03 '20 at 00:31

1 Answers1

2

I think you are after this kind of thing:

enter image description here

Or, if we get wider:

enter image description here

If that's the idea, then one key mistake is when you say:

bottomStackView.distribution = .fill

You actually want .equalDistribution. To demonstrate, I created the example entirely in code, so you can see all the settings:

let sv = UIStackView()
sv.translatesAutoresizingMaskIntoConstraints = false
self.view.addSubview(sv)
sv.leadingAnchor.constraint(equalTo: self.view.leadingAnchor, constant: 20).isActive = true
sv.trailingAnchor.constraint(equalTo: self.view.trailingAnchor, constant: -20).isActive = true
sv.bottomAnchor.constraint(equalTo: self.view.bottomAnchor, constant: -20).isActive = true
sv.heightAnchor.constraint(equalToConstant: 160).isActive = true

sv.distribution = .equalSpacing
sv.alignment = .center

let v1 = UIView()
v1.translatesAutoresizingMaskIntoConstraints = false
v1.widthAnchor.constraint(equalToConstant: 120).isActive = true
v1.heightAnchor.constraint(equalToConstant: 150).isActive = true
v1.backgroundColor = .red
sv.addArrangedSubview(v1)

let v2 = UIView()
v2.translatesAutoresizingMaskIntoConstraints = false
v2.widthAnchor.constraint(equalToConstant: 80).isActive = true
v2.heightAnchor.constraint(equalToConstant: 80).isActive = true
v2.backgroundColor = .yellow
sv.addArrangedSubview(v2)


let v3 = UIView()
v3.translatesAutoresizingMaskIntoConstraints = false
v3.widthAnchor.constraint(equalToConstant: 120).isActive = true
v3.heightAnchor.constraint(equalToConstant: 150).isActive = true
v3.backgroundColor = .blue
sv.addArrangedSubview(v3)
matt
  • 515,959
  • 87
  • 875
  • 1,141