7

I have a UIStackView which consist of 5 elements. I want the centered one bigger than others (like in below pic).

How I create UIStackView()

stackView.axis  = UILayoutConstraintAxis.horizontal
stackView.distribution = UIStackViewDistribution.fillEqually
stackView.alignment = UIStackViewAlignment.bottom
stackView.spacing = 0.0
stackView.addArrangedSubview(supportedServicesView)
stackView.addArrangedSubview(incidentView)
stackView.addArrangedSubview(contactUsView)
stackView.addArrangedSubview(moreView)
stackView.addArrangedSubview(moreView2)
stackView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(stackView)

stackView.anchor(nil, left: self.view.leftAnchor, bottom: self.view.bottomAnchor, right: self.view.rightAnchor, topConstant: 0, leftConstant: 0, bottomConstant: 90, rightConstant: 0, widthConstant: 0, heightConstant: 0)

How I create my custom UIViews subview positions;

override func updateConstraints() {
   logoImage.anchor(self.topAnchor, left: self.leftAnchor, bottom: nil, right: self.rightAnchor, topConstant: 0, leftConstant: 0, bottomConstant: 0, rightConstant: 0, widthConstant: 0, heightConstant: 0)
   label.anchor(self.logoImage.bottomAnchor, left: self.leftAnchor, bottom: nil, right: self.rightAnchor, topConstant: 10, leftConstant: 0, bottomConstant: 0, rightConstant: 0, widthConstant: 0, heightConstant: 0)
super.updateConstraints()

}

EDIT: when I add width anchor to centered view, It gets higher width but because heights are same, It doesn't look like bigger.

contactUsView.widthAnchor.constraint(equalToConstant: self.view.frame.width / 5).isActive = true

EDIT 2: When I give height constraint to any view inside UIStackView, Stackviews position (height only) changes to value which I gave to Views height anchor.

Emre Önder
  • 2,408
  • 2
  • 23
  • 73
  • You should give a width constraint to the one you want bigger. – bseh May 21 '18 at 13:24
  • Hmm how can I do that? with mybiggerview.frame.size = CGSize(width..)? – Emre Önder May 21 '18 at 13:28
  • yourBiggerView?.widthAnchor.constraint(equalToConstant: widthYouWant).isActive = true – bseh May 21 '18 at 13:29
  • It gives "Unable to simultaneously satisfy constraints." error after I add width anchor to view. – Emre Önder May 21 '18 at 13:32
  • I think you need to change .fillEqually to .fillProportionally – Scriptable May 21 '18 at 13:33
  • When I make it fillProportionally, error gone but now It doesn't look like I want. Centered view seen on a very different part of the screen. I edited my question. – Emre Önder May 21 '18 at 13:58
  • I was trying to do this last week and never found a solution that didn't throw an error in the terminal. In the end, I just set up constraints dynamically in code and avoided the stack. – D. Greg May 21 '18 at 14:26
  • @D.Greg I know I can do in that way but If we can do like this, It will be so clear code :D can you please give vote maybe we can put some attention from iOS GURUS! – Emre Önder May 21 '18 at 14:27

1 Answers1

8

I have just implemented this example in a playground.

The UIStackView uses the intrinsic content size to calculate how to place its arranged subviews in the stack view taking the axis, distribution, spacing etc into consideration.

So if you add both a height and width constraint you should see it working. See the example and screenshot of output below.

//: Playground - noun: a place where people can play
import UIKit
import PlaygroundSupport


let stackview = UIStackView(frame: CGRect(x: 0, y: 0, width: 500, height: 150))
stackview.backgroundColor = .white
let colours: [UIColor] = [
    .blue,
    .green,
    .red,
    .yellow,
    .orange
]

for i in 0...4 {

    let view = UIView(frame: CGRect.zero)
    view.backgroundColor = colours[i]
    view.translatesAutoresizingMaskIntoConstraints = false

    if i == 2 {
        view.heightAnchor.constraint(equalToConstant: 130).isActive = true
    } else {
        view.heightAnchor.constraint(equalToConstant: 80).isActive = true
    }
    view.widthAnchor.constraint(equalToConstant: 75)

    stackview.addArrangedSubview(view)
}

stackview.axis  = .horizontal
stackview.distribution = .fillEqually
stackview.alignment = .bottom
stackview.spacing = 0.5

PlaygroundPage.current.liveView = stackview

Playground Screenshot

You can drop this code straight into a playground and tweak the settings for spacing, distribution etc to get the desired output.

Scriptable
  • 19,402
  • 5
  • 56
  • 72