UILabel max height with AutoLayout - ios

I have a multiline UILabel inside a custom keyboard extension. I want this label to grow to fill the content up to a certain height, at which point I want it to just cut off the rest of the text.
Because the keyboard has different heights depending on the device and orientation, I can't just set a simple less than or equal height constraint.
What I tried was to constrain the bottom of the label to the top of the buttons below, with a greater than or equal constraint. This works to a certain extent, but causes the keyboard to grow in size as opposed to the label being forced to cut off its text.
How would I force the label to a max height, without directly using a height constraint on the label?

Put the label in a UIView and constrain the view's height to less than or equal.

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.

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"

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 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.

Autolayout constraints to make UILabel more sensitive to taps

I have 2 tappable labels grouped within a parent view (The attached screenshot shows 3 of these views). Currently the size of each label is set to fit its content. Therefore a tap gesture is only recognized when the tap is directly on the text. I want to be able to tap above or below the text (but within its parent view) so that a tapped label is triggered. What type of constraints would I need to add between the views so that I’m able to do this?
You could add minimum widths and heights to the labels, and that might do what you want (width >= minimum). Alternatively, you could add these labels as the child of a larger UIView that does the gesture recognition. You should add constraints to that UIView so that it expands as the UILabels expand, and again, you'd still need minimum widths and heights.
You would add a height constraint to each label. This is not normally needed, because a label has an intrinsic content size (intrinsicContentSize) that is used to generate its height automatically, through two low-priority constraints that cause the label to resist getting larger than or smaller than the intrinsic height. But if you simply add a height constraint, you can make the label taller, overriding the intrinsic content size; this works because your constraint has a higher priority than the intrinsic height constraints.

Resources