Confused about why autolayout doesn't seem to grow subviews to match constraints

In my app, I have a Scene which has the following layout:

View

  • Scroll View
    • View (called "noSidewaysView")
      • Three Stack Views
      • Text View 1
      • Text View 2


In this layout, noSidewaysView has the following constraints:

  • Trailing, Leading, Bottom, and Top to Superview with constant = 0 for all four
  • Equal Width to Superview
  • Height Equals 500 @ 250
  • Height ≥ 500 ( @ 1000 )

The topmost stack view is constrained to Trailing, Leading, and Top to the noSidewaysView.

The second stack view is constrained to Trailing and Leading to the noSideways View, and Top to the topmost stackview's bottom (set to Standard Value).

The third stack view is constrained to Trailing and Leading to the noSidewaysView, and top to the second stackview's bottom (set to Standard Value).

All three stack views contain items with intrinsic content sizes.

Text view 1 is constrained to Trailing and Leading to the noSideways view, and top to the third stackview's bottom set to Standard Value. It is also height constrained = 75.

All of these constraints (except Text View 1's height) are set to "0".

Text View 2 is constrained to Trailing and Leading to the noSidewaysView with a value of "0". It has a Bottom constraint to the noSidewaysView of "0". It has two height constraints, Height = 156 @ 250 and Height ≥ 156 @ 1000. It also has a Top constraint to Text View 1's bottom, which is set to Standard Value.


To me, that should result in Text View 2's top being pinned to Text View 1's bottom, and at 156 pixels high unless there is more room, in which case it is at least 156 pixels high but stays pinned to the bottom of the noSidewaysView (which is pinned to the bottom of the Scroll View, which is pinned to the bottom of the View at the topmost spot in the hierarchy).


What I am seeing, however, is that Text View 2 is always exactly 156 pixels high, no matter what happens. If I remove the height = constraint, it complains (and, I think, understandably) about ambiguous layouts.


There are no layout issues in the Scene, yellow or red. I feel like I am missing a vital link, here, that will allow me to understand why Text View 2 doesn't stay pinned to the bottom of the noSidewaysView (and, therefore, the bottom of the Scroll View), even though I think it probably ought to. I tried changing Text View 2's Top constraint priority to 999 to allow the Bottom constraint to be the slightly more important, but that had no effect on it.


Edit: I neglected to point out that Scroll View is pinned top/bottom/leading/trailing to the topmost View.

You declare :


In this layout, noSidewaysView has the following constraints:

  • Trailing, Leading, Bottom, and Top to Superview with constant = 0 for all four
  • Equal Width to Superview
  • Height Equals 500 @ 250
  • Height ≥ 500 ( @ 1000 )

Some constraints seem redundant, notably

Equal Width to Superview

Because it has 0 distance to superview in all 4 directions, so width and heigth are equal to its superview.


It is normal that you get 156 always : The priority for the constrains will be applied in order to resolve a conflict between two different constraints. But if both can be staisfied, they will be, so = 156.


You have to play with Content Compression resistance priority (set vertical to 751 I think)

See : h ttps://stackoverflow.com/questions/15850417/cocoa-autolayout-content-hugging-vs-content-compression-resistance-priority/16281229#16281229

Re: the equal width; you'd think that, but no. It doesn't work that way.


With all of those constraints: https://software.quixoticraindrop.com/images/xcodeIB/full.png

With only the width = superview removed: https://software.quixoticraindrop.com/images/xcodeIB/not%20equal.png


I got the original concept from an early autolayout tutorial, if I can dig the link from my history I'll post it (for context).


That did occur to me, that height = 156 would always be satisfiable which was why I made it such a low priority; It seems to me that if the height ≥ 156 with a higher priority, it should take over, but that doesn't seem to be the way it works. Same with the height =/≥ 500 on Text View 2's superview. I removed the text view 2's height =, leaving only the height ≥ constraint, without change (also, without complaint from autolayout; however, trying to remove both that height = and the height = for the noSidewaysView does result in an autolayout complaint, ). Modifying both the vertical hugging (to 249, then to 251) and vertical content compression (to 749, then 751) one at a time, first on the noSidewaysView and then on Text View 2, had no effect. Also, putting the height = 500@250 and height ≥ 500 (@1000) on the Scroll View does not fix the "Need constraints for Y or height" error, it only disappears when its subview, noSidewaysView, has a height constraint.


This was the tutorial I was using for reference on the scrollview in autolayout: https://spin.atomicobject.com/2014/03/05/uiscrollview-autolayout-ios/

Also, it doesn't change anything to move those height constraints to the Scroll view (aside from the still-extant height error that adding those constraints doesn't resolve). That is, by putting the height = and/or ≥ size constraint on the Scroll View instead of noSidewaysView, it has no effect on whether or not Text View 2 grows its bottom to stay pinned to the view.

Re: the equal width; you'd think that, but no. It doesn't work that way.


With all of those constraints: (images are in the "Currently under moderation" comment, which has been in that status for several hours)

With only the width = superview removed: (images are in the "Currently under moderation" comment, which has been in that status for several hours)


I got the original concept from an early autolayout tutorial, if I can dig the link from my history I'll post it (for context).


That did occur to me, that height = 156 would always be satisfiable which was why I made it such a low priority; It seems to me that if the height ≥ 156 with a higher priority, it should take over, but that doesn't seem to be the way it works. Same with the height =/≥ 500 on Text View 2's superview. I removed the text view 2's height =, leaving only the height ≥ constraint, without change (also, without complaint from autolayout; however, trying to remove both that height = and the height = for the noSidewaysView does result in an autolayout complaint, ). Modifying both the vertical hugging (to 249, then to 251) and vertical content compression (to 749, then 751) one at a time, first on the noSidewaysView and then on Text View 2, had no effect. Also, putting the height = 500@250 and height ≥ 500 (@1000) on the Scroll View does not fix the "Need constraints for Y or height" error, it only disappears when its subview, noSidewaysView, has a height constraint.

==== above here, is copy/pasted from a reply I posted earlier which is still "Under moderation"

While I am waiting for somebody to moderate my reply with the links in them, I figured I'd at least see if the text of my reply helps.


Basically, without the Equal Widths constraint, the noSidewaysView will not stretch to fill the visible width of the super. I tried it and it doesn't work. Also, it doesn't work with only Equal Widths, both Trailing/Leading to superview constant = 0 and the equal widths are necessary for the elements inside to fill the space.

So, I've tried setting the hugging & resistance each, both up and down, on the bottom Text View, and I removed the height = 156 constraint (but kept the height >= 156 constraint) on Text View 2. In order to resolve ambiguous height on that scene, I needed to make sure one of either the Scroll View or the noSidewaysView had an explicit height constraint. I tried each of them with a height = 500 individually, with no difference between them.


The bottom of Text View 2 will not stay on the bottom of the view, period. I turned the priority on the top = Text View 1 bottom, then removed it completely, and that didn't help (I would think that if it saw a constriant to keep the bottom to the superview with a higher priority than the top, that it would take precedence, but that doesn't seem to be the case).


So it appears that there are no autolayout options that will allow the bottom of Text View 2 to stay aligned with the bottom of its superview. The only way for this to maybe work appears to be to calculate the size of the bounds of the phone's view area and then set the size of the views at runtime. That, however, seems to be what autolayout is supposed to prevent, is exactly that.


I'd love to post a picture that shows what's going on, but images can't be posted directly and putting URLs in the comments apparently requires a moderation that borders on impossible to get (it's been 98 hours).

You can put URL. just replace https by h ttps

Confused about why autolayout doesn't seem to grow subviews to match constraints
 
 
Q