Make one view bigger than others inside UIStackView()
Asked Answered
S

1

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.

Sacramental answered 21/5, 2018 at 13:23 Comment(8)
You should give a width constraint to the one you want bigger.Goggin
Hmm how can I do that? with mybiggerview.frame.size = CGSize(width..)?Pyle
yourBiggerView?.widthAnchor.constraint(equalToConstant: widthYouWant).isActive = trueGoggin
It gives "Unable to simultaneously satisfy constraints." error after I add width anchor to view.Pyle
I think you need to change .fillEqually to .fillProportionallyUpolu
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.Pyle
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.Faiyum
@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!Pyle
U
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.

Upolu answered 21/5, 2018 at 14:51 Comment(3)
nice. I don't believe view.widthAnchor.constraint(equalToConstant: 75) is needed nor it's getting usedSouterrain
No the fill option is overriding that by the looks of itUpolu
UIStackView doesn't respect its backgroundColor property, as it's a non-drawing view.Maniacal

© 2022 - 2024 — McMap. All rights reserved.