AutoLayout to dynamically size UILabel Height and Width - ios

I have one UILabel and One UIView contains other subviews side by side in Storyboard. The UIView should butt up against the right edge of the UILabel(trailing constraint of 1), but I also need the UIlabel (the one on the left) to set it's width equal to it's content size unless it hits a max width. Visually:
|Label text| |UIViewWithSubviews|
And I need the following constraints:
1) Label should resize width wise unless it hits a max size and height is also dynamic that means when text reaches the maximum width then the word wrap will break the sentence to another line. and UIview will become vertical to UIlabel.
2) UIView should always be butted up against the right edge of label one in vertical center.
How do I set this up in Storyboard?
Thanks In advance.

Is this what you need?
Here is how i did in Interface Builder.

1) Set a width constraint on the UILabel that is "Less Than Or Equal" to the max width you want.
2) Set the number of lines for the UILabel in the storyboard to be 0. This enables the wrapping you are looking for. Don't set any height constraint at all.
3) Set up constraint to center the UIView vertically with the UILabel.
4) Your other existing constraints sound fine. Just make sure that the UILabel has a clear x and y position, for example by anchoring to the leading and top edges of the superview. And make sure the UIView similarly has sufficient constraints as needed in addition to the vertical centering and the leading edge alignment with the UILabel.

Related

How do I make the UIView superview of a UILabel fit the intrinsic height of the UILabel using the storyboard only?

I got a UIView whose child is a UILabel. I then aligned the left, top, right, and bottom of the UILabel to that of its superview (the UIView) using constraints.
But what I'm getting is a UILabel that matches the height of its superview but not its intrinsic height (smaller or larger than its text content depending on the size of the UIView). What I expect is for the UIView to resize itself to fit exactly the height of the UILabel.
So how do I do this using only the interface builder?
In order to make the UILabel keep its size and force the outer view to resize you can update the values for Content Hugging Priority to 1000 (a.k.a. Required). This can be done in the measurements panel when selecting the label in Interface Builder.
I think they are set as a default to 750.
This should (if there is nothing else causing the change) make the label take its intrinsic content size and force its superview to conform to that size also.
Align top, trailing, bottom and leading of UILabel with UIView (add constraints).
Remove height and bottom constraints from UIView if any.
If the content is large, you probably need to wrap UILabel into a UIScrollView in place of UIView. and add a bottom constraint to UIScrollView
Content Hugging Priority of UILabel (251) is more than that of UIView (250) by default. Verify this
It's super easy using auto-layout. Just, follow these steps
1 - Drag a UIView and align it vertically and horizontallyin centre.
2 - Now drag UILabel into the UIView and align the label also horizontally and vertically in centre.Now, the IB aligns the label at the centre WRT to the superview and not the UIView.So, change that in the size-inspector section.
3 - Once you have done that and all red lines are removed, select both the label and the UIView together using the command key.
4 - Now, give them constraints as follows
leading = 0, trailing = 0 and select the equal width and equal height.
There you are done.If you wanna test that the UIView size is respective to the label's content, try increasing the label's font to a bigger size and you will see that the size of the view will be the same as the size of the label.
There , you are done :-D. Hope, this was helpful.
If someone is experiencing this issue, while:
Having 2 labels inside the UIView
Doing everything what was suggested here
In my case, I set Vertical Content Hugging Priority of BOTH UILabels to 1000. Then one of the labels had a different font. (ie. one label was supposed to be smaller than the other one)
The height was being ambiguous, because both labels were trying to force their height on the superview. Once I lowered the priority on the smaller label, everything worked fine.

Position UILabel in Storyboard

I am trying to position a UILabel within a UIView on a storyboard, without any code. I'd like the label to have an X position of 1/4 of the width of the UIView. So, if the width of the UIView is 400, I want the UILabel to be at X = 100.
Is it possible to do this on the storyboard with constraints without code?
You need to create a constraint such that the leading edge of your label is equal to the trailing edge of your superview with a constant of 0 and a multiplier of 0.25.
To create this in the Storyboard:
control-drag from the label to the right edge of its superview.
Choose Trailing Space to Container from the pop-up.
Now edit the constraint. Click on the I-bar that connects your label to the right of its superview. Open the Attributes Inspector. Choose the First Item pop-up and select Reverse First and Second Item.
The First Item should now be the Trailing edge of your label. Click on that and change it to Leading.
Change the constant to 0.
Change the multiplier to 0.25. (Note: You can also use 1:4 or 1/4 if those seem more intuitive).
First give all other constrains to the UILabel.
to set X position as 1/4 of the width of the UIView
Consider trailing margin of Superview. If trailing margin is 60, then width of the view will be 60
You can use a accessory clear-color view to help get that:
Firstly, create the superview(blue view), and set the constraints
Secondly, you can use a assist view, set it's width is 1/4 of the blue view
1) When you set the assist view's width constraint , you can drag the assist view to the blue view, choose the Equals Width, the in the Size inspector you can edit the width constraint's Multiplier to be 1:4
2) Set the assist view's background color to be clear
The result is this:
The third step, you can drag the label, set the label's left constaint to the assist view
Apart from the answer below what you can do is add a bottom and trailing of your UILabel to your superview. Now control-drag your UILabel to your superview and select the equal width constraint and set the multiplier to 0.75.
The above will allow your your UILabel to always have a width of 3/4 to your superview and since it will have a trailing of 0 to your superview there will always be a space offset by 1/4 the width of your superview

How to use scrollview with subviews of a dynamic height?

I have a label inside a scrollview that has can be as few as 1 lines and as many as 10 lines. I'm having trouble figuring out how to make the scrollview content size dynamic so that it will stretch accordingly.
I tried adding a height constraint of >= 100 (arbitrary number) but then it complained about it being an Inequality Constraint Ambiguity.
Quick answer
Remove the current height constraint on your label.
Ensure the labels Lines property is set to 0 and Line Breaks is set to Word Wrap.
Add vertical spacing constraints to the views above and below the label.
Ensure that every view has vertical spacing constraints from the top to bottom margins, in order for the scroll view to infer the height of its contentView.
Explanation
In order for the scroll view to infer its content size it must have constraints from margin to subviews to margin - imagine it like a balloon the content is the air inside that pushes on the wall to make the balloon the size it is. The constraints from the subviews to margins allow the size of the subviews to push the walls of the content view out.
For the label setting the Lines property to 0 means it will have a variable amount of lines just as you want. The Line Breaks property being set to Word Wrap means it will ensure words are not cut off (truncated) or broken up into characters and instead pushed onto the next line as whole words.
If you don't specify a height constraint for a UILabel it will take a height that fits the whole text. Just make sure that number of lines is set to 0 and that your label has all the margin constraints set.
This tech note from Apple explains how to correctly configure a scrollview with scrollable content using auto layout only https://developer.apple.com/library/ios/technotes/tn2154/_index.html.
Conceptually, in your case, this is what you need to do:
View hierarchy:
MainView -> ScrollView -> ContentView -> UILabel
Scrollview is constrained to all edges of the main view,
ContentView is constrained to all edges of the ScrollView
and the UILabel is constrained to all edges of the ContentView (set UILabel number of lines to 0 and remove the height constraint you currently have applied)
The key here is to realise that the size of the contentView only depends on the size of the UILabel so as the UILabel height stretches so does the contentView. This will allow the scrollView to automatically infer the contentSize and enable scrolling if required.

XCode Interface Builder Auto Layout issue

i have UILabel (red colored) on top and UIScrollView (blue colored) at the bottom of it. I have set all constraints for UILabel and at the same time I have set UIScrollView Top Space To: UILabel = 10.
Now when my app is loaded everything looks good. But, i am dynamically changing height of my UILabel depending on its text and logically when height of UILabel increases UIScrollView should automatically go down to keep constraint. But this does not happen. ScrollView stays as it is and overlaps with increased UILabel.
Here is what you should do.
With all of your current settings,
Don't use height constraint for label,
set number of line to 0 to label
You don't need to add any calculation of height of label, it will adjust it's height according to text
PS: if you want to have some height constraint to set minimum height of label, you can use "Greater or equal to instead of equal"

How to simulate conditional hugging priorities in AutoLayout?

I have a UIView that contains a multiline UILabel and a UIImageView. The imageView is a square that is a specific height and width and is centered vertically in the cell, while the label is constrained to the top of the view. Here's a little illustration:
I want to be able to make the parent view expandable based on either the UILabel or the UIImageView, based on which one has the bigger height. How would I go about doing this (in Storyboard)?
You would set a bottom and top constraint for both the label and image view at a high priority. Set the constant equal to the amount of padding you'd want.
Then, on the parent view, you'll want to add a height constraint with a lower priority than the top/bottom constraints of the label and image.
That way, you guarantee padding between the label/image and their superview, which will force the superview to expand its height since its priority is lower than that of the padding.

Resources