iOS Layout Constraints | Width anchor vs leading and trailing anchors - ios

I haven’t been using AutoLayout constraints for long, so I haven’t fully grasp some of its inner workings.
In particular, are there times I can use the widthAnchor and the leading and trailing anchors interchangeably, and others that I need all 3? Or, is valid to use the widthAnchor with the leadingAnchor or the trailingAnchor?
To sum up my question, is the combination of the leading and trailing anchors just defining the width and the X axis position of a view, just as the widthAnchor with the leadingAnchor would?

Basically, the auto layout needs at least two constraints for views having an intrinsic size and at least four for views without having an intrinsic size. Let's say your view has an intrinsic size(eg. UITextView), it's just enough to constraint the x-axis and y axis. If you wish, you can specify the fixed size with width anchor and height anchor or dynamic size with constraining top, bottom, leading, trailing anchors based on the screen size but this is just optional. If your view doesn't have an intrinsic content size(eg. UIImageView), you need to specify at least one x-axis, one y-axis and width and height anchor or constraint leading, trailing, top and bottom anchors. The point is if you have the leading and trailing anchors, you don't need to specify width anchor and vice versa. Now, you get the idea. If you constraint top and bottom anchor, you shouldn't add height anchor to avoid conflicts.

Related

Interface Builder not honoring Safe Area alignment constraints

In Interface Builder, setting the constraints for a UI element (let's say a button) doesn't change if I make the aligment proportional to the Safe Area or proportional to the Superview.
I have a button which I set its horizontal alignment to be:
I have another button which I set its horizontal alignment to be:
Both buttons end up being aligned horizontally:
I would have expected the button aligned to the Safe Area to be shifted to the right as the Safe Area's leading edge is shifted to the right from the one of the Superview. I'm probably missing something but can't quite understand what is going on here.
The problem is that heights and widths proportional to the Safe Area are honored, so the size of UI elements does change if you make them proportional to the Safe Area or to the Superview. So when you try to layout something with Safe Area proportional heights and widths, and also use Safe Area proportional horizontal and vertical placements, UI Elements don't line up for iPhones with a notch. They kind of lineup for devices like iPads and iPhones with no notch where the Safe Area is very close to the Superview area.
Couple things may be causing the confusion...
First, it helps to add a (yellow) view, constrained on all 4 sides to the Safe Area (using iPhone 13 Pro layout):
As you can see, the Safe Area has 44-pts Leading AND Trailing.
So, in Portrait Orientation, both the Superview and the Yellow view have a Width of 390.0 and the CenterX value for both is 195.0.
When rotated to Landscape, the Superview Width is 844.0 while the Yellow view (constrained to Safe Area) Width is only 756.0 ... that is, 44-pts on each side.
However, the CenterX value is the same: 422.0
So, when we constrain a view / label Leading to CenterX of either the Superview or Safe Area with a 0.5 Multiplier, the resulting X / Leading value will be 422.0 * 0.5 == 211.0
Take a look at this example using these constraints:
L1 Leading is Superview.centerX * 0.5
L2 Leading is SafeArea.centerX * 0.5
L3 CenterX is Superview.centerX
L4 Leading is L3.centerX * 0.5
L5 CenterX is SafeArea.centerX
L6 Leading is L5.centerX * 0.5
L7 CenterX is Superview.centerX (but Width: 240 instead of 120)
L8 Leading is L7.centerX * 0.5
As we see, all of the "50% of CenterX" labels are aligned.
And, we get the same alignment when rotated:
Worth noting: If you try to do the same thing with Top and CenterY constraints, you WILL see an immediate difference... because when rotated to Landscape Orientation, the Safe Area Top and Bottom "padding" are not the same.

Autolayout minimum gap between UIStackViews

I have 3 UIStackViews laid as follows edge to edge:
SV1 ---- SV2 ---- SV3
SV1 sits at a fixed distance of 5 points to superview leading, SV2 center is aligned with center of superview, and SV3 is at a fixed distance of 5 points to views trailing. Problem is on iPhone SE, SV2 is too wide and too close to SV1 and SV3. How do I set autolayout constraints so that SV2 is at a minimum distance D to SV1 and SV3?
You can create two constraints: first between sv2 and sv1 and second between sv2 and sv3. The trick is to set the constraint not equals to a a value but greater than.
You can create horizontal spacing constraints between the stack views and set them to greater-or-equal. This takes care of the minimum space between them.
But since they were to close together this means at least one of them has to get smaller to make space for the separation. You control which one by setting the content compression resistance priority of the views inside your stack views. The one with the lowest value shrinks.
If all three stack views have different widths you also could lower the priority of the center constraint to a value below the spacing constraints priority. That would mean that the center view is pushed to one side to make room for the spacing.
There are lots of possibilities that depend on your exact views. The best way is to experiment a bit with the priorities.

iOS Auto-Layout Max-Width

So I'm trying to build a view that obeys the following. On smaller screens, the view will match the trailing and leading constraints to consume 100% of the width excluding the 32px margin. On larger screens, the view will not exceed a width of some constant, let's say 480px.
I've looked into it, and I tried setting the trailing and leading constraints to have a lower priority than the <= width constraint, however, on screens smaller than 480 pixels for example, the view will expand beyond the bounds of the screen. Essentially, I'm trying to use auto layout to use 100% width with 32px margin up to 480px. How do I fix my constraints?

set label position with priority constraint?

I have one label to the right side of parent view.On top of label there is a view.I have given below constraints to label.
Align leading to top view (constant<16) LOW PRIORITY
Top space from parent view
Trailing space to parent view (constant=28) HIGH PRIORITY
I want when text inside the label increase it should change it's position.it should move towards left but at the same time it should also move towards right.I mean should increase it's width in both directions.As of now it's only moving towards left & keeping fix position from right.
Please tell how can i achieve this task?
i think if you set center alignment for label alignment you should get answer you want.Also give same priority to leading and trailing.
This will not work as the trailing space to super view constraint will most likely always win, as you have observed.
The width and height of the label is taken care of by its intrinsic content size and hence no constraints are needed for that. As far as position goes, the y is taken care of by the top space constraint. Finally the x will need a constraint that will allow it to grow in both directions as mentioned. To enable this behaviour remove the leading and trailing constraints and add a horizontally centered constraint. This will centre the label to its super views centre. To offset the position left or right you may choose a constant value or use the multiplier property.
The multiplier is good for positioning a certain percentage of the superview regardless of its size. e.g.: if the superview is the root view then a multiplier value of 0.5 places the label quarter of the way across the view, 1.0 makes the centre x align exactly, 1.5 makes it 3/4 across from the left.

iOS layout why does center constraint not enough?

I really don't understand the logic of this ... well ... strange iOS layout system.
I place a UILabel with the constraint Align center X to Superview.
Why does it complain to need a new constraint for X position ??
center is center no?
You need to tell more about the horizontal positioning of the view. Centering the view does not say wether it has a fixed width or it should keep the leading / trailing space around view.
Here are two possible options (there is also a fixed height with a fixed aspect ratio, as #Moshe said in his answer):
Your view will always have a width of 61 (for example):
Your view will have a fixed leading and trailing space on the left/right side:
That warning is a misnomer. It doesn't mean there's no constraint. It should say that "there aren't enough constraints to calculate an X position."
You need to add a constraint for X the position, but you also need to give enough constraints to for auto layout to figure out the width of your view.
You can either provide a Leading Space and a Trailing Space, or you can provide a Width, or you can provide a Height and a Ratio. Autolayout just needs something to work with.
If you actually have added a center x constraint, that should be enough for auto layout to calculate the x position. But are you sure you didn’t set a center y constraint instead? The directions that you drag the lines in Interface Builder can be confusing, so you might have accidentally set a y constraint when you meant to set an x constraint. If you are trying to center x, you will still need a constraint for the y position, whether it’s vertical centering or space from top or bottom to the superview or some other view.

Resources