Most of the interviews common question is "How many minimum constraints are required for one UI object" Can someone please clarify?
Regardless of what are the constraints (how would you determine the appropriate constraints), basically, the minimum required constraints are the constraints that should determine the size and the origin of the component (height, width, x and y).
Keep in mind it is not only required to specify each property by its own literal constraint, for example, you could determine what is the width of the component by setting leading and trailing constraints to it instead of equals constant width. Furthermore, components with intrinsic content size should not have always fixed size (height and width), hence determining their origins (x and y) would be sufficient, unless there is a need to setup their constants.
To be short, excluding the case of an UIScrollView where the content size is involved as well, you need 2 distinct constraints per axis (horizontal and vertical).
It's also important to note that if an UI element has an intrinsic size, that counts as a constraint for that axis already, even though it can be overridden with constraints that have higher priority.
Related
I have a problem with multiplier and cannot understand how this feature works. For example i have view has 6:1 multiplier(To SuperView.Leading) as below.
When i change the multiplier to 2:1 it seems like below picture.
My question is in the 6:1 relation what does 6 and 1 mean. And also in 2:1 relation what does 2 and 1 mean. Similar consider you have three view like the picture below. Totally there 4 blank areas between subViews and superView. How can i say every blank area must be the SuperView.Width / 6 (and every blank width must be equal)
Thanks in advance.
When working with autolayout, especially when you are working with proportional layouts, you have to use multiplier.
I have to explain here some mathematics.
We know straight line equation.
Y = Mx + C
In above equation. Assume M is your multiplier and C is your Constant.
Thus suppose you have superview (in case of iphone 6s plus) of
414(width) x 736(height) size. On that view suppose you created subview.
Now if you want subview size exacly half of superview size, then just drag two constraints from subview to superview. (i.e. Equal Width and Equal Height)
See this Image
Obviously now you will get an error. just like I'm getting. (See below Image)
Now click on both of the constraints one by one, and use multiplier as 0.5. Then use above straight line equation.
Here 0.5 means you want width of subview = superviewWidth / 2.0 i.e. 207 px.
In other words you can provide multiplier as 207:414 also.
Y i.e. subviewWidth = ((M i.e. 0.5) * (x i.e. 414 i.e. superviewWidth)) + (Constant i.e. Zero)
Finally you get subviewWidth = 207 px
Similarly do for height of subview. Provide multiplier 0.5 or 368:736.
When done all things, don't forget to click on subview and update frames.
This way constants and multiplier will works.
Multiplier is there for creating Proportional Constraint. Auto Layout calculates the first item’s attribute to be the product of the second item’s attribute and this multiplier. Any value other than 1 creates a proportional constraint.
In your case, 6:1 means multiplier is 6/1 = 6. Which means
view.leading = Superview.leadingMargin*6
replace : with / - you will understand what it means.
In my example multiplier is 1:2 = 0.5
height red view is 0.5 times greater than the superview
When it comes to the multiplier it depends on what constraints you are dealing with. You have the views leading constraint connected to the superview leading margin. When the constant is 0 that gives you an 8 points gap. When you change the multiplier you will be effecting that gap. That's why when you do 2:1 you see it go to the right 8 points. Essentially multiplying the original 8 point gap by 2. If you do 1:2 it will go from 8 points to 4 points, essentially dividing the original 8 point margin by 2.
Now when you look at Adrians example, he only multiplied it by 1:2 so how did that make it half of the entire screen? That's because he did that on the height constraint. The view was originally the full size of the superview, but when he multiplied it by 1:2, he indicated that he wanted it to be 1/2 of its original height. Giving you that end result.
So the important thing to understand is that multiplier may seem to act different depending on the situation but that's because it depends on what constraints you are dealing with.
here is a good answer that goes into this more:
Understanding multiplier in auto layout to use relative positioning
the link details how if you wanted to make the leading edge 10% and trailing edge 90% you would need to set both constraints in relation to the trailing edge.
Multiplying the trailing constraint by 0.9 and the leading constraints by 0.1.
In regards to your question about the equally separated views, you should use a stack view. They were made for situations like this so you didn't have to deal with all the constraints. You just need to set constraints for the stack view and configure it accordingly.
I am new to autolayout and I want to understand the constraints of autolayout.
my question is ->
When we apply constraints between two objects it gives you 3 options in relation tab which are equal, less than or equal to and greater than equal to.
So I want to understand when to use less than or equal to and greater than equal to sonstraint.
If possible please help me with some small demo.
I think this will help you.
suppose you want a UILabel to resize maximum height to 80 pixels depending upon its inner content and if more test are displayed in the label then it should truncate its tail but should not increase its height because you have other elements on screen which will not look good if the label will increase more then that. So here you should use height <= 80. So if you set some minimum value of the label like height >= 40 so if the text of the label is not enough to fit in 40 height then it will stay 40 pixels but if text increases then it will increase max up to 80. So here you came to now about the use of greater then or equal to also. Like if you want a element to be minimum some value and if its resizing at runtime then should not be less then any value, then you can use those constraints. I can describe in brief if needed. Thanks.
when I want to make a constraint saying that the layout system can have minimum 5 and maximum 53 points between two views, such as
ViewA.Leading is greater or equal ViewB.Trailing 5 (pri 1000 multiplier 1)
ViewA.Leading is less or equal ViewB.Trailing 53 (pri 1000 multiplier 1)
Interface Builder always gets upset with me, giving me the "Inequality Constraint Ambiguity" error. If this is not the way to make such a constraint, how should it be instead?
(please, I insist on expressing the constraints in a storyboard through Interface Builder)
Cheers
Nik
The ambiguity is that the auto layout system doesn't know exactly how much space to put. You have successfully placed limits on the range of allowed space, but there are still any number of solutions. For example, 20 points works, but so does 40, and so does 31.2875.
The system needs additional information to pick a specific distance. How much space, specifically, would you prefer if all other constraints allow flexibility?
You could, for example, set a constraint ViewA.Leading equal to ViewB.Trailing plus 20 but at a lower priority. The lower priority would allow it to be overridden by higher priority constraints and things such as content hugging or compression resistance priority. But, all else being equal, the system will try for 20 or as close to 20 as possible. That removes the ambiguity.
But, ultimately, you need to decide how the system should resolve things when there are remaining degrees of freedom and give the system the corresponding constraints to eliminate that freedom, so it can come up with one right answer.
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.
I'm confused about how Cocoa's Autolayout determines whether a layout is ambiguous. Here's a simple example:
The observed behavior is as follows. The spacers to the left and right of the green rectangle are always the same width. When you stretch the superview horizontally outwards, the spacers stick to 80 while the rectangle expands. When you shrink the superview horizontally, the rectangle sticks to 398 while the spacers shrink to 10, after which the rectangle continues to shrink. At no point is the layout labeled ambiguous by IB.
However, you'll notice that the horizontal layout is defined almost entirely by inequalities! From what I can see, when the rectangle has a width of > 398, there's no reason for the spacers to have a width of 80. They could have a width of anywhere from 10 to 80 and still satisfy each horizontal inequality. That sounds ambiguous to me, but IB clearly does not agree.
There must be some implicit rule I'm missing. Please help me out!
Auto layout has, coincidentally, ambiguous documentation. Therefore, the behavior you observed from your application is technically undefined. Here is exactly what the documentation says:
Constraints have a priority level. Constraints with higher priority levels are satisfied before constraints with lower priority levels. The default priority level is required (NSLayoutPriorityRequired), which means that the constraint must be satisfied exactly. The layout system gets as close as it can to satisfying an optional constraint, even if it cannot completely achieve it.
The requirements are therefore
The layout system gets as close as it can to satisfying an optional constraint
Constraints with a priority of 1000 must be satisfied exactly
Higher priority constraints are satisfied before constraints with lower priority levels
However, as you have noticed
What causes the spacer to greedily expand to 80, versus the green rect expanding maximally on account of it having a higher priority?
Auto layout does not define "close as it can" and "Higher priory constraints are satisfied before constraints" in a unambiguous manner. The Auto layout documentation mentions these two dimensions: priority and closeness; but these documents do not say how the optimization of these dimensions interact.
With that being said, here is one theory of how auto layout could operate based on the fact that auto layout is probably a multi-variable linear decomposition solver.
Let's consider your corner cases
When you stretch the superview horizontally outwards the spacers stick to 80 while the rectangle expands
When you shrink the superview horizontally, the rectangle sticks to 398 while the spacers shrink to 10
after which the rectangle continues to shrink
These corner cases can be reduced to
Case A - superview > 398+80+80 (Spacers fixed at 80, rectangle expands from 398)
Case B - superview > 398+10+10 (Rectangle fixed at 398, spacers contract from 80 to 10)
Case C - superview <= 398+10+10 (Spacers fixed at 10, rectangle contracts from 398)
Notice how the numbers never jump from case to case. There is a smooth connection from Case A to Case B in the spacers, going from 80 -> 80 at the critical points. The same occurs for the rectangle from Case B to Case C. The algorithm used by auto-layout always results in a smooth solution when dealing with critical points.