Can't seem to make auto layout work right

So I have a Split View controller for my app.


The Master View Controller does not want to layout correctly in different sizes, so I figure I must be doing something wrong.


This is the layout, the way it shows in the iPhone 4s:


I very carefully set up stack views, as shown:


"Topmost" includes two items (Size of ... label, and the Help and Reset buttons) in a horizontal stack view, and the segmented controller.

"Roll Settings" includes three Vertical Stack Views (L-R: Labels, Selection settings, and Steppers).

"Toggles" includes two Horizontal Stack Views, which each includes a label and switch associated with the label.


As it stands, I set the following constraints:

Topmost Stack view: Leading & Trailing Space to container, Top Space to Top Layout Guide, and set all of those stupid "helpful" settings from 8 to "Standard" where applicable.

Roll Settings: Leading & Trailing Space to container, Top Space to Topmost Stack View, all set to "Standard."

Toggles: Leading & Trailing Space to container, Top Space to Roll Settings, all set to "Standard."

Roll with …: Align Center X to Superview, Top Space to Toggles, all set to "Standard."

Current Settings Display: Leading & Trailing Space to container, Bottom Space to Bottom Layout Guide

I then added a contstraint for "Roll with…" to be Bottom Space to Current Settings Display and set it to "Standard."


Layout is fine on iPhone 4s.

When I switch to the iPhone SE, the "Roll with…" button is centered, but shows a yellow dashed box:

Indicating it is in the wrong location. It is pretty clear to me that it wants to be up just a few pixels, but can't be because of conflicting constraints; however, removing either the Top Space or Bottom Space constraint will not build (generates errors with auto layout that cannot be resolved).

I think I get that it's torn between deciding which of the constraints to follow, but even if I change the priority to 750 or 250, nothing changes, which it should if the constraints confict, which they don't really seem to.

I should note that the button isn't the only 'yellow' item in the view, the Toggles Stack View and Current Settings text view are also yellow (but neither the Topmost nor the Roll Settings Stack Views are, they are both blue):

I tried removing one constraint, the Top Space of "Current Settings," which resulted in this:

… about which XCode generates an error saying that the "y" position of that text view is ambiguous (which sort of makes sense; even though I gave it leading/trailing edge information and the bottom space, it's unclear how tall it should be).

With these constraints, all of the Stack Views, the main Button, and the Text View are all blue, but then moving to another size class they will not line up correctly, and I think they probably should.

Ergo, I believe I must be misunderstanding the value, or use, of Stack Views, size classes, and constraints.

What am I missing?

Answered by junkpile in 156007022

That all sounds fine from what I can tell. It's quite possible you are running into Xcode bugs with stack views in IB. 😐 Does it lay out correctly without warnings on device / simulator? FWIW, the only time I've tried to use nested stack views (in a tvOS app a few months back) I did run into wacky IB behaviour like that. Constantly misplaced views in IB. After hitting "update frames" enough times in a row it would settle down with no warnings, until the next time I changed anything or reopened the file. It seemed to work OK on the device so I just chalked it up to typical Xcode bugs. My iOS apps all need earlier deployment targets so I haven't used any stack views on iOS recently.


Does your text view have the "scrollable" checkbox ticked? It shouldn't, if auto layout needs to calculate its vertical size based on its contents. If it is scrollable, then you probably need an explicit height constraint on it.

Glad to be of some help. Auto Layout seems to be fairly smart; Xcode storyboard view, not so much, sometimes.


> Now, I just have to figure out why it won't let me specify a different layout for landscape mode


To me that's the biggest glaring brain damage of the whole size classes system. It's not like anybody actually uses different layouts for landscape vs. portrait on an iPad, right? 😝 Why would anyone want to do that? LOL

In my case, it's the iPhones, especially the 4s & SE that cause the most heartache.


Since my app uses a master->detail, the iPad layout works right. On the smaller 4s/SE screen, shifting into landscape mode is a complete disaster in the Master, with elements missing, things on top of other things. The screen size is fine, but only if I can reposition elements on the landscape mode. Unfortunately, even Vary For Traits for Width & Height doesn't actually introduce locations for elements only on the specified size class, but rather replaces the existing ones.


But, that's another show (sorry Alton). If I feel less frustrated with it later, I may open a different topic and see if anyone else is having similar issues.

LIUHAI

LIUHAI

Can't seem to make auto layout work right
 
 
Q