set label position with priority constraint? - ios

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.

Related

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.

What is horizontal offset in iOS (UILabel)?

I'm following a tutorial that had us set a UILabel to be aligned horizontally in the container (center horizontally) and set the offset by 40. The instructor then set the trailing top space distance to the nearest UILabel above it. At first, I thought the offset was another way of setting the trailing top space distance, but I must be wrong. I was wondering what it exactly does?

How to specify a constraint for a UILabel to remain centered beneath each segment of a UISegmentedControl?

In my app for iOS 8, I have a UISegmentedControl that stretches to fit the width of the device's screen. So on an iPad it's more pixels wide than it is on an iPhone 6+, which is more pixels wide than the iPhone 6, etc.
Centered just beneath each segment of the UISegmentedControl, I have a UILabel. So there are 5 segments and 5 UILabels. Each UILabel has a fixed width (fixed by constraint). However if the display size increases they become uncentered.
How in Interface Builder can I specify a constraint that will force each UILabel to become centered beneath each segment? I would be happy if I could just get the elements to remain proportionally spaced with each other as the display size scales, but I can't figure out how to do that, either.
All I can seemingly do is to center the middle UILabel directly under the middle segment by specifying a Center X Alignment between that and the UISegmentedControl.
I specified a Horizontal Space constraint between all the UILabels, and between the outer UILabels and the edges of the view, and set all these to "greater than or equals". They all have the same priority, but strangely, they don't all scale proportionally to each other.
The resulting problem is that the amount of Horizontal Space between each of the UILabels does not scale smoothly as the width of the device's screen increases. If I align everything to be in the proper positions on the iPhone 5S width of screen, then on the iPad their alignment is all wonky, and only the middle one lines up with its segment. The rest of them are all off center.
It appears that there is no way to specify a percentage of the over-all display width as a constraint -- you can only specify things in terms of pixels. Really?!?!
Clearly I could make the width of the objects to be flexible, but because they are text labels with right-aligned text, that screws everything up.
Surely I'm missing something here... since the point of Auto Layout is to make your interface scale according to the screen size, surely there is a way to specify a constraint as a percentage of any given view or subview... surely!!! But how? I've read the documentation and I cannot, for the life of me, figure it out.
BTW I did see that in the past, people have used crude hacks like spacer views or multiple sets of constraints, but surely those are outdated answers, and I'm just overlooking something extraordinarily obvious... right?
You can do this by making the centerX constraint of your labels equal to the superview.trailing times 0.1, 0.3, 0.5, 0.7, and 0.9 with constants of 0. To make these constraints, add your 5 labels to the view. Give the left most one a vertical spacing constraint to the segmented control. Select all 5 labels and give give them a "vertical centers" alignment constraint. Now control-drag from each label to the right side of the screen, and select the "Trailing space to container margin" constraint. Edit each one of these trailing constraints to look like this (except for the multiplier that needs to be given the values I mentioned above):
You'll have to reverse the first and second item (which you do from the pull down on the first item), change the Label.trailing to Label.Center X, and uncheck the "relative to margin" box, then correct the constant and multiplier values.
This approach will only work if the segmented control stretches all the way across the screen with no padding to the edges. If you want padding to the edges, then you need to use a completely different approach. You would need to create 5 UIViews below your segmented control -- align the left edge of the left-most one to the left edge of the segmented control. Align the right edge of the right-most one to the right edge of the segmented control. Give the 5 views equal width, and 0 length horizontal spacing constraint from each to its neighbor. This will give you 5 views that mimic the segmented control in width, with each view being the same width as one of the segments (assuming all the segments are the same width -- if that's not the case, you're screwed). Then you only need to add your labels as subviews of these 5 views, and give them centerX and centerY constraints.

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.

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