Expanding UIView as UILabel inside grows - ios

I have a UIView which is a superview of UIImageView and UILabel. UILabel can have different size depending on the amount of text in it. So, I need the UIView to grow and shrink together with the UILabel but can not make it working.
The screenshot of how it looks is below:
As you can see the spacing above and below of the label are too big. In the .xib I set up top and bottom constraints on the UILabel to be just 10 but apparently these are somehow violated. UIView has top constraint to the frame above with the image as >=10, so that it could grow from 10.
You can see .xib below:
I tried to increase Content Hugging Priority of the UIView but it does not help. UILabel has just 4 constraints: top, bottom, left, right relative to its superview UIView. I have also tried to change Content Hugging Priority of UILabel relative to UIView but no success. The UIImageView is the actual border of the UIView that is shown in the picture.

Think you're missing:
View:
Constraint: Height >= 20
Label:
Lines: 0
Constraint: Top and bottom margins to the (super) View
Constraint: Height >= 10
Screenshot of a working example:
Tip: use the preview

So, in my case the solution was to set constraints of UILabel relative to the UIImageView and then set the Content Compression Resistance Priority to 250. Then everything started to work. Thank you matt! I opened your github project and found that Content Compression Resistance Priority of UIImageView should be 250 - this was crucial.

Set the label to .sizeToFit(), or in InterfaceBilder the number of lines to 0, and either you set the max width (prefererred width) or make >=/<= constraints. As my experience, you have to play a bit with constraints to make it work, the preview in assistant editor is very useful in that case. Then you can set the width/height of the superviews to be the same as the label and some to make it bigger. Hope this works.

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.

Limit the height of a UILabel inside a UIScrollView

I have a UILabel inside a UIScrollView and the contentSize of the UIScrollView is determined by the amount of text in the UILabel. I have managed to define a minimum height for the contentView inside the UIScrollView by making the height, width and aspect ratio constraints optional.
This is how the hierarchy of the UIScrollView looks like -
UIScrollView
contentView
UILabel
In some cases, even when the text is huge and makes the label expand beyond it's frame, I wish to have the frame of the UILabel stick to it's square frame with the extra text getting truncated. I am using autolayout so I believe this won't be possible by merely setting the frame of the UILabel and it has something to do with changing the priorities of the constraints.
Constraints for the UILabel -
The UILabel has its leading, trailing, top and bottom connected to the contentView.
Constraints for the UISCrollView-
Required
Trailing, Leading, Top and Bottom to the superview i.e. the UIScrollView
Optional
Equal height and width to the superview (UIScrollView) and aspect ratio = 1:1
EDIT
And I need to do it in a way that when I set the lineBreakMode of the UILabel to NSLineBreakByTruncatingTail, the text automatically gets truncated and textLabel.text only returns the visible text.
Ok, so if I understand everything correctly, you want to have an expandable label that either shows its entire text, or has a square form. This should as easy as enabling/disabling a constraint such that label.height <= label.width (or ==, depending on what you want it to look like if there is less text then would fit a square label). You can create this constraint in interface builder, add an outlet for it and then simply do:
self.labelSquareConstraint.active = YES/NO;
As to the question in your edit : there is no easy way to get the visible part of the text from a label, but there are some threads on SO about this, for example :
Get truncated text from UILabel
UILabel visible part of text
Calculate the range of visible text in UILabel

AutoLayout to dynamically size UILabel Height and Width

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.

iOS - Make UIImageView resize to fit UILabel with AutoLayout

I'm having this issue since quite some time now and it's driving me crazy: I have a UILabel with text that can be dynamically changed, and I have a UIImageView that should act as the text's background. I would like the UIImageView to resize itself to always fit the UILabel's text.
"Paid" could become "Free", or "Payant" in French for instance, and the box behind should always resize.
Using Storyboard, I have tried adding a UIImageView with the UILabel on top of it, and setting the constraints of the UILabel to the UIImageView, but this ends up resizing the UILabel to the UIImageView's size. I cannot set a fixed width or height for the UIImageView because it should adapt.
My second try was to make a UIView, recategorize it as a UIIimageView, add the UILabel as a subview, make the UIView resize to the UILabel and add the image programatically but once again, no success.
What is the right way to do this?
For the first method, I assume you set the had the label and the image view have the same vertical and horizontal centers as well has the same height and width. The problem is the layout engine is assume the intrinsic size of the image is more important than the label. To change that you need to change hugging priority and the compression resistance of the views. Go to the size inspect of the label (picture) and increase the hugging priority to required. This will for it's height and width to be it's intrinsic height and width. You could also decrease the image view's compression resistance, so it is more amendable to being sized down.
The constraints for the label:
You can change the top and leading to place it in the appropriate spot in the view.
The constraints for the image view:

IOS Label and View constraints height

I am really confused about constraints is iOS, i've read a lot of articles, but get stuck, when tried to set Height constraints of UIView according to UILabel content height. I know that is the common question, but i really don't understand the solutions. I thought that the main thing in this question is the constraint priority, but i can't set them properly. In one case, the height of UIView wont change to 0, and in other UILabel height does not make any sense.
So. I've got:
UIView with height constraint, and descendants constraints (below)
UIImageView with height=32, width=32, top=10, left=10, bottom>=10
UILabel with left to UIImageView = 10, top=10, right=10, bottom=10
And i want:
If i got any text to place in the UILabel, i want to dynamic height of UIView according to height of content size of UILabel.
And if there is no text to place in UILabel, i want to set the height of UIView equals to 0 (hide the UIView totally).
UIImageView - is just the icon. If there is no text, must be shrink to 0, if there is some text, must have height 32, top constraint 10, bottom constraint more or equals to 10.
UPD:
Fix the problem, by adding height constraint programmatically. (don't like this)
You can make the constraints take full control of the label,image and view heights, if you set the priorities correctelly.
Set the four vertical margins priorities to less than 1000 (lets say 999)
Set the image height priority to 999 too.
Set lable vertical hugging priority to 1000
Set image height less than or equal label height with 1000 priority
Set label height less than or equal container view height with multiplier 1: 10(or any big number) with priority 1000
Like this
The View is this
and this

Resources