Trying to align with autolayout - ios

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.

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.

View changes size depending on device screen size, but should have a fixed size

I have created an orange circle using a UIView100 height and 100 width with a radius of 50. This was done in the 4 inch setup.
When i move up to the 4.7inch or higher the circle becomes distorted.
What do i do so that the circle doesn't get distorted when displayed on larger devices?
So I guess you used Xcode's “Reset to Suggested Constraints” option, like this:
When you do that, Xcode guesses what constraints you want. Unfortunately, in your case, it guessed wrong. It did create the centering constraints you wanted, but it did not create the width and height constraints you wanted. Instead it created leading edge and top edge constraints, like this:
So when you load your scene on a larger device, in order to satisfy those constraints, auto layout has to make the view larger, like this:
To fix this, you need to delete the edge constraints:
And add width and height constraints:
So your final constraints on the subview look like this:
With these constraints, when you load your scene on a larger device, the subview will stay centered and not change size:
I'm betting you used a fixed corner radius to make a circular UIView (which would have a constraint for 1:1 aspect ratio too). Just make it so the radius of the corners is calculated somewhere where the right dimensions for the view can be known. viewDidLayoutSubviews is a good place as it'll take care of other resizes like screen rotation.
override func viewDidLayoutSubviews() {
self.circleView.layer.cornerRadius = self.circleView.frame.size.width / 2 // Assumes width == height because of 1:1 aspect ratio constraint
}
Alternatively don't make the size of your view depend on the width or height of the screen (i.e. remove constraints to the sides, center it and give it a fixed width and height)

Increase aspect ratio according to screen size- iOS

A view at the bottom of a view controller with the following constraint:
leading - 0
trailing - 0
bottom - 0
aspect ratio - 7:1
it looks good on small screen sizes, but on larger screen the view looks too small. What is the best way to increase the aspect ratio according to what screen is using the application
Instead of having aspect ratio set, use proportional height and proportional width. To do so:
1- Select your view and set its height equal to the height of its superview
2- Click Edit and then change "proportional" to whatever you want:
Now you have a view that will be proportional to its superview height. Do the same for its width if you need it.
To be more precise, you can play with the priority of the constraint. For instance keep your ratio constraint and set its priority to 999.
Then change both proportional constraints (those we just add) constant to ">=" instead of "=". Then try different values of multiplier to see how the view react. By doing this you might need a maximum height/width constraint as well (as the view won't know in certain cases which size to choose).

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.

Adding relative constraints the iOS layout

I want to set relative constraints to layout elements like the image below:
1) the white square must be on the top right corner filling 50% of the horizontal content.
2) the central globe must be relative to the screen size. example: on 3.5 inch device must be smaller, on 5.5 must be greater. like 75% of the screen width.
0) Clear all constraints for sanity.
.
.
1/4 SQUARE
1) Resize your view to kind-of fit the intended size.
2) Select the square view and add margin constraints.
3) multiselect the root view and the view
4) Add equality constraint of width and height.
5) Select the equal height constraint and then the equal width constraint and change the multiplier to 2 for both constraints.
DONE
0) Clear all constraints for sanity.
. .
CIRCLE
1) Put the circle view roughly into the middle.
2) Select it and add these two constraints.
3) This circle is a UIView which is a rectangle so it has width and height that are independent from each other....but we need to keep them equal..so we need to put an Aspect Ratio Constraint.
4) And finally ..we need to give it some size (width == height here). Let's make the size dependent on root view width. Multiselect again both the circle view and the root view..and add the equal width constraint. Also experiment with ratio. 1.6 looks good to me for a start.

Resources