iOS - Make UIImageView resize to fit UILabel with AutoLayout - ios

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:

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.

Expanding UIView as UILabel inside grows

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.

iOS UITableViewCell dynamic sized tableview cell with imageview and label

In my app i have a UILabel and a UIImageView under each other. Both of them have a fixed width, but their height supposed to change.
I want the UILabel's height to change to fit the text it's holding and i want the UIImageView's height to change automatically to fill the width and keep it's aspect ratio.
My problem is that autolayout doesn't allow me to have both item's vertical content compression resistance priority to the same constant. Because of this one item will always oppress the other.
What i expect is the tableviewcell to change it's height dynamically to fit its content.
I do not want to modify anything from code.
You can do it in alot possible way like
1.) Using StackView here is a link to help http://www.raywenderlich.com/114552/uistackview-tutorial-introducing-stack-views
2.) You can select your UILabel and its superView than select aspectRatio , in a same way select your UIImageView and the superView than select aspectRatio.
It will help Thanks.

Don't specify width & height constraints on my UIView (like UILabel can do)

If I put a UILabel in a view and specify a vertical space constraint and an horizontal space constraint, it's fine.
If I do the same with my custom UIView, IB will complain because it'll lack an height and a width constraints.
I guess it comes from the fact that UILabel can expand both vertically and horizontally. But so does my custom UIView, so how can I inform that my view has such rights?
The default behaviour for a UILabel is "Fit To Content"(Editor-> Fit To Content). This means that UILabel will grow as the Content increases for a given font size. For a view to position itself, it needs X, Y, Width and Height. Width and Height are given by the text it contains. Rest two properties you have already provided. I hope that answers your question.

How to set this kind of constraints: UIImageView's width based on UILabel's Length in AutoLayout?

I already set UIImageView.width(Green Color Background) == UILabel.width + 20 in my tableView cell ,but when the label's content changing , the label 's height is changing at first ,but I want the label to grow wider first , if it can't be more wider then grow higher. what 's the problem here
Hi yes you can do it. I am explaining below how can u do it with auto layout.
At the time of applying constraint, instead of giving hight and width
to UIImageView just try to give it three constraint with UILabel which
are " Equal Width, Equal Height and Aspect Ratio"
For Applying these three constraints with UILabel the shortcut is just
drag and drop your mouse cursor from UIImage to UIlabel with right
click only, so you can see above three options. After applying it ,give
UIlabel Leading and trailing constraint( or whatever u want) and most important thing, set
your UIlabel to size to content fit. For UILabel,shortcut is just
click on UILabel and click on top toolbar's tab EDITOR and you will
find option for setting UILABEL as size to content fit so after
setting it UILabel will automatically set its frame as per its content
and so as UIImageView.

Resources