Setting up variable constrains in xcode - ios

I'm having trouble setting up constraints.
This is the thing I am trying to achieve:
I have 2 objects A and B. I want there there to be a maximum of 100 points between A and B if its a larger screen, or less if its a smaller screen.
Also, I want there to be a minimum of a 20 point margin from the main view controller. So on a smaller screen the minimum spacing will be 20 points, and on a larger screen the margin can be as wide as needs in order to satisfy the space between A and B at 100 points.
To illustrate how I want it to look on various screens:
4 inch screen
I want there to be a 20 point margin on either side and the middle (space between A and B) can be variable, i.e. 100 or less.
5.5 inch screen
The margins can be variable and expand as large as they need to, but the middle section (space between A and B) can be a maximum of 100.
Any help how to achieve this would be greatly appreciated.

This can be achieved with help from three dummy views and two width constrains with different priorities. I set up a test project to test my thought. check it out to see whether it's what you needed
https://github.com/dopcn/testSeg

Related

Creating a dynamically sizing UILabel in the Xcode interface builder

I want to be able to create a UILabel that will adjust it's size in a more complex way than normal AutoLayout. I've looked over the internet for an answer to this, but to no avail.
Here's what I want it to do.
Say you're viewing it on an iPhone. I want it to be 16 points away from either edge centered in the middle. (Height does not matter in any of this)
However, when the screen gets wider, I want the UILabel to stretch so that it's 16 points away form each edge UNTIL it reaches, say, 500 width. Once it reaches 500 width, I don't want it to get any wider. This is where the 16 points on either side increases, still keeping the label in the center.
Now you're viewing it on an iPad landscape. The UILabel is exactly 500 points wide and in the center.
If possible, I would like to be able to accomplish this using AutoLayout, and not code, but if code is a must, I can deal with that.
Thank you for your consideration. All help is appreciated.
You can do this with 3 constraints:
center the label horizontally in the view
set a width constraint of <= 500
set a leading space constraint of 16. Give this a priority of < 1000.
When the view is wide (like on an iPad), the label will stretch to its full width of 500. Auto Layout will keep the label centered, and it will try its best to satisfy the 3rd constraint by keeping the the leading space as close to 16 as possible. It chooses to break this constraint because the priority is less than 1000.
When the view is narrow (like on an iPhone), the label will have a leading space of 16 (and trailing space of 16 because the label is centered). The width will be whatever is left, because that satisfies the width <= 500 constraint.

set subViews with different width horizontal in a superview

I wanted to create 6 subviews in a view, which have different width & same height. It should fit horizontal, all screen resolutions for iPad and iPhone.Can anyone please help me on this.
Without any additional logic (i.e., which views to make smaller or not if the content does not fit), you can do this like this: if the views are ligned up from left to right and numbered 1 to 6
defining the leftmost view (1) with a distance to left edge
defining the rightmost view (6) with a distance to right edge
defining the distances between the views (i.e. 1 to 2, 2 to 3 etc.)
setting the horizontal "compression resistance priority" to differing values
You can set the same height individually, or just for one view and as equal height for the other views.

AutoLayout Understanding Multiplier

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.

Understanding Autolayout Constraints

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.

iOS Autolayout: Issues with 2 variable sized boxes and 1 fixed sized box

I have now been bashing my head against this problem for a couple of hours and figured it was time to ask somebody else.
I have 2 views that must be the same size, within these two views there are 2 boxes (green and blue in the pictures below), which are of variable sizes, and a box (pink'ish) that is fixed size.
Here is a sample image:
The green and pink boxes are set to be at the top, and the blue box floats underneath them. The blue box should never be further down than 15pt from the lowest of the other two boxes. This means that if the green box becomes smaller (as seen in the next image), then the blue box should stay 15pt from the pink box.
Lastly, since the cells are fixed height then if the blue box becomes smaller, then it should stay at the other boxes, but leave space below itself to fill out the rest of the view (since it must be as big as the view next to it), as I tried picturing here:
The key point here is that we are working on the smaller view of the two.
(The green and blue boxes are both labels with text that must be at the top of the box.)
The best solution I've come up with is to add:
green.bottom >=15 blue.top
pink.bottom >=15 blue.top
blue.bottom >=15 superview.bottom
But I get an "Inequality Constraint Ambiguity" between them, because inequality is not "good enough".
You need to add two more constraints between the blue view and the green and pink views. The should be,
green.bottom == 15 blue.top priority 900
pink.bottom == 15 blue.top priority 900
Your >= constraints have the default priority of 1000, meaning that they are required. This will ensure that neither view is ever closer than 15 points to the blue view. Adding these new equal constraints with a lower priority, means that the system will try to satisfy them, but it doesn't have to. This will result in the system satisfying which ever of those two equal constraints that it can, without violating the >= constraints.
I'm not exactly sure what constraint you need to the bottom of the view (from the blue view) since I'm unsure what size you want it to be.

Resources