Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UIStackview with differently aligned subviews

I'd like to align the Blue and Purple views to the center of the screen, and I'd like to align the green view to the left of the screen:

enter image description here

Here is my code:

view.backgroundColor = UIColor.orangeColor()

//Stackview: 
let stackView   = UIStackView()
stackView.translatesAutoresizingMaskIntoConstraints = false
self.view.addSubview(stackView)

stackView.topAnchor.constraintEqualToAnchor(self.view.topAnchor).active = true
stackView.leftAnchor.constraintEqualToAnchor(self.view.leftAnchor).active = true
stackView.rightAnchor.constraintEqualToAnchor(self.view.rightAnchor).active = true

stackView.axis  = UILayoutConstraintAxis.Vertical
stackView.alignment = .Center

//Blue view: 
let blueBox = UIView()
stackView.addArrangedSubview(blueBox)
blueBox.backgroundColor = UIColor.blueColor()
blueBox.heightAnchor.constraintEqualToConstant(140).active = true
blueBox.widthAnchor.constraintEqualToConstant(140).active = true

//Inner stackview that contains the green view: 
let greenBoxContainer = UIStackView()
let greenBox = UIView()
stackView.addArrangedSubview(greenBoxContainer)
greenBoxContainer.addArrangedSubview(greenBox)
greenBoxContainer.alignment = .Leading

//Green view:
greenBox.backgroundColor = UIColor.greenColor()
greenBox.widthAnchor.constraintEqualToConstant(120).active = true
greenBox.heightAnchor.constraintEqualToConstant(120).active = true

//Purple view: 
let purpleView = UIView()
stackView.addArrangedSubview(purpleView)
purpleView.backgroundColor = UIColor.purpleColor()
purpleView.heightAnchor.constraintEqualToConstant(50.0).active = true
purpleView.widthAnchor.constraintEqualToConstant(50.0).active = true

To repeat, how can I align the left edge of the green view with the left edge of the screen?

I tried this:

greenBoxContainer.widthAnchor.constraintEqualToAnchor(stackView.widthAnchor).active = true

but it only stretches the green view through the length of the screen.

like image 948
Eric Avatar asked Dec 15 '15 17:12

Eric


People also ask

What is Stackview alignment?

A layout where the stack view aligns the center of its arranged views with its center along its axis. case leading. A layout for vertical stacks where the stack view aligns the leading edge of its arranged views along its leading edge.

What is fill proportionally in Uistackview?

case fillProportionally. A layout where the stack view resizes its arranged views so that they fill the available space along the stack view's axis. Views are resized proportionally based on their intrinsic content size along the stack view's axis.

How does UIStackView work?

The stack view aligns the first and last arranged view with its edges along the stack's axis. In a horizontal stack, this means the first arranged view's leading edge is pinned to the stack's leading edge, and the last arranged view's trailing edge is pinned to the stack's trailing edge.

How remove all Subviews from Stackview?

To remove an arranged subview that you no longer want around, you need to call removeFromSuperview() on it. The stack view will automatically remove it from the arranged subview list.


1 Answers

One way is to add a spacer view:

let greenBox = UIView()
stackView.addArrangedSubview(greenBoxContainer)
greenBoxContainer.addArrangedSubview(greenBox)

let spacer = UIView()
greenBoxContainer.addArrangedSubview(spacer)
spacer.rightAnchor.constraintEqualToAnchor(greenBoxContainer.rightAnchor).active = true

greenBoxContainer.widthAnchor.constraintEqualToAnchor(stackView.widthAnchor).active = true
greenBox.backgroundColor = UIColor.greenColor()
greenBox.widthAnchor.constraintEqualToConstant(120).active = true
greenBox.heightAnchor.constraintEqualToConstant(120).active = true

Note that I'm no longer setting greenBoxContainer's alignment, so it defaults to .Fill. Thus the right edge of spacer is flushed to the inner stackview's right edge, and it takes up all the width, leaving greenBox just enough room to satisfy its width constraint.

But this is a workaround, I'd like to be able to specify alignments without having to create spacer views..

like image 175
Eric Avatar answered Oct 06 '22 00:10

Eric