I have a UIStackView
inside a vertically scrolling UIScrollView
with everything constrained using Auto Layout. The scroll view fills the superview, the stack view fills the scroll view, and various elements are added into the stack view. To allow this to play nicely with Auto Layout and define the scroll view's content size, you have to also specify the width of the stack view. That is done by adding a width constraint on the stack view, equal to the width of the scroll view. At this point nothing is ambiguous, it behaves exactly as desired.
Now, if you want to add margins so that the elements aren't stretching to the far left and right edges of the screen, you can change the leading and trailing constraint constants on the stack view to inset 15pt on both sides for example. But then you have to be sure to change the equal width constraint constant to -30. And that has worked well, insetting the scrollable contents, still allowing you to swipe at the far edges of the screen to scroll.
Now, the iPhone X comes along, and 15pt padding is no longer sufficient when in landscape because content is being placed underneath the housing sensor. So you need to update this to set the margins to respect the safe area layout margins. You really just want to use the default margins. You could change your stack view's leading and trailing constraint constants to use the view's layout margins (which respects the safe area insets), but this will not work because your equal width constraint constant is no longer double the amount of margins, the margins are dynamic now.
So, one way to resolve this is to create IBOutlet
s for the stack view's leading and trailing and width constraints, then programmatically adjust them all when the layout margins change (viewLayoutMarginsDidChange
). But I'm wondering if there's a better approach, preferably a solution that works within in Interface Builder, no code required.