Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using UIStackView to center single view

I've been trying to setup a simple container view in IB using UIStackView. I want this container to center its only arranged subview and respect the intrinsic content size of the subview.

Unfortunately for all possible configuration of alignment and distribution the subview is stretched to fill the width along the axis.

This looks like a weird edge case or a bug, because once I add a second view everything behaves as expected and both subviews maintain their size defined by intrinsic content size method.

I would love to understand why UIStackView behaves like that.

like image 863
Robert Wijas Avatar asked Jul 19 '15 19:07

Robert Wijas


1 Answers

UIStackView creates constraints with a priority of 1000 (the maximum allowed priority), which is UILayoutPriorityRequired. Auto layout is required to satisfy these constraints if possible.

Your constraint at “high” priority (UILayoutPriorityDefaultHigh == 750, I presume) conflicts with the stack view's required constraints, so auto layout will ignore your constraint.

If you set your constraint priority to 1000, then auto layout will not be able to satisfy all required constraints. It will log an error, and it will break one of the constraints. You don't get to pick which constraint it breaks.

Note that it only needs to break one of the three constraints to solve the system, and it can break any of the three conflicting constraints. However, breaking any single one of the three conflicting constraints won't leave a system that centers your view. Your view should end up either stretched, or hugging one end of the stack view, depending on which constraint auto layout breaks. And a future version of iOS might change auto layout so that a different constraint is broken and the layout changes.

It's not clear why you're trying to use a stack view to center your view. If you just have one view and you want to center it, make its parent a plain UIView instead of a UIStackView, and set up constraints to center your view in the parent view.

If you're using a stack view because sometimes you want more than one arranged subview in the stack, then you should add two hidden spacer views (one at each end of the axis) in addition to your content view(s). Create an equal-width or equal-height constraint between the spacers.

like image 136
rob mayoff Avatar answered Oct 16 '22 12:10

rob mayoff