Interface Builder not honoring Safe Area alignment constraints - ios

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.

Related

How to prioritize one constraint over another when the font gets larger

I have a UILabel with the following constraints:
- Align Center Y to Superview (priority 750)
- Top Space to View, greater than equal to 0 (priority 1000)
In normal mode, the UILabel is align center to Y which is ok. But if I go to Accessibility setting and set to large fonts (maximum size) I want my label to use the Top Space with greater than equal value.
Right now is still using the Align Center to Y in both cases. Is there a way when the font is large to use the other constraint with higher priority ?
PS: below this label there are 2 other labels which get shrunk when font is large, because top view label stays in the middle of screen instead of moving up.
Try this
- Bottom space to view, equal to zero (multiplier 2)
- Top Space to View, greater than equal to 0
Screenshots
Project - https://github.com/leninsmannath/AutoLayoutBottomFromCenter.git

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.

Set max width to constraint

I have rectangle with four constraints. All works ok, but on ipad this rectangle is too big. So is there a way to set max margin for constraints. i tried set Relation value to "gather then" or "less then" but it not works.
Constraints have a field for priority. This is a case where you want to use that. It looks like you want your rectangle to be centered, so I would recommend the following constraints:
CenterX of rectangle equal to CenterX of superView. Priority 1000
CenterY of rectangle equal to CenterY of superView. Priority 1000
Width of rectangle less than or equal to maximum size you want for iPad. Priority 1000
Height of rectangle less than or equal to maximum size you want for iPad. Priority 1000
Vertical constraint for distance from top of superView. Priority 750
Horizontal constraint for distance from leading edge of superView. Priority 750
On iPhones, all of the constraints will be met because the rectangle will easily be smaller than the maximum size for iPad.
On iPads, the higher priority width and height constraints will keep the rectangle from growing too big, and Auto Layout will allow the top and leading edge constraints to be broken to make that possible, but it will make the rectangle as big as possible to come as close as possible to meeting the horizontal and vertical offsets.

Autolayout bottom spacing constraint is not obeyed

I have a UIButton and a UILabel constrained to be a standard distance from the bottom of the Superview. Works well on the iPad, but on the smaller iPhone screens, when other elements take up too much space, these views are pushed off the edge of the screen despite their constraint to remain a standard distance from the bottom. Why is this so?
What I would like to have happen is for the four rectangles to shrink in size so that there is still room for the "Go Back" and "Question" label to remain a standard distance from the bottom. The four rectangles can maintain aspect ratio and equal width/height by all shrinking at the same ratio. I have no constraints on their needing to be equal to or larger than a certain size. I've tried lowering their Content Compression Resistance Priority as well.
Configuration:
(I have also tried "equal" and "<=" in top spacing between "Go Back" & bottom left rectangle)
("Greater than or equal" works best on iPad to keep "Go Back" at the bottom of the screen)
How it looks on iPhone 6 and iPhone 6+ - with the labels cut off at bottom:
Did you try to lower those four buttons' height constraint's priority??
For example like this, try to set them to 750
You can make this work with a couple of changes and additions. Give the leading and trailing constraints between the top 2 rectangles and the superview a lower priority (I used 749), but still keep them as "equal". This will keep them at the standard distance from the edges if it's possible, but will allow them to have a larger spacing if the vertical space combined with the aspect ratio requires it. The problem with this, is that since they aren't required any more, when those constraints need to stretch, there's nothing that says they have to stretch equally; therefore, we need some way to keep the rectangles centered. So, instead of a spacing constraint between the left and right top rectangles, add a small view (I used 8x8) that has a centerY constraint to one of the rectangles, and zero constant spacing constraints to the two rectangles. Give this view a centerX constraint to the superview; this construct will give you the same spacing between your rectangles that you had before, but will keep them centered in the superview while allowing them to shrink in width (and height to keep the aspect ratio) if need to accommodate the vertical space.

Trying to align with autolayout

I have this view hierarchy on a viewController
view
| |_____ redView
| |______orangeView
|
|
|_______ blackView
blackView height is always 126 pt. orangeView has a 127:155 aspect ratio and is inside redView. The result is this seen on iPhone 3.5".
Now I would like to make this scale proportionally to all iPhone sizes. Doing it on Photoshop, I would like it to be like this:
Notice two things: orangeView should keep its aspect ratio and the iPhone 4 is the only one where the organgeView height is the same as redView's. On the other phones, what is the same is the width.
Because of this, I cannot figure out what constrains I should apply to orangeView to make it scale like I want.
What I am obtaining is this:
The constrains I have so far for orangeView are these: centerX to redView, centerY to redView, aspecratio (127:155) and same height of redView, but this last is incorrect and the reason why I am having the result I have. How can I make orange view expand to reach the maximum horizontally or vertically, keeping its aspect ratio, on all devices and continue to be completely within redView area?
I think you can do what you want by setting the width and height of the orange view equal to the red view, but with low priority (I used 250). Also you need one that says the orange view is <= the width of the red view with a priority of 1000 (otherwise the orange view extends past the red view's bounds in the width direction).
So, the ones that say equal width and equal height to superview both have a priority of 250.

Resources