Why UILabel's height become zero if doesn't hold any text? - ios

I expected from the label to keep the minimal height of one line even if you remove the text out of it.
Here's the picture:
How it should look (but without whitespace):
If I enter the one whitespace in it, its height gets corrected. But I dont want to put whitespace into empty labels. there should be a better solution.

The UILabel control have an intrinsic content size so if you don't have any text his height will be zero, If you need a min height then you must define a Height constraint with >= your minValue as I said in my comments
I think you can figured it out how do this

First, add a Width and a Height constraints:
Second, change the Equal to the Bigger Than(both for width and height, height could be small one, like 8):
Finally, you are able to change the font size of label freely, the label will became bigger with the bigger font size. And the label size will be (42,8) if you removed text:

One workaround is to use a UITextField instead, set isEnabled to false, and set the placeholder property to " ".
As long as you don't need it's width to ever be shorter than the width of a single space -- UITextFields' sizes are calculated using the placeholder property by default -- then this will always have the height of a non-empty UITextField regardless of whether it contains text or not.

Related

How can I set the height of a UITextView to exactly match its truncated content?

I have a UITextView whose height I would like to limit to some reasonable value, with the text truncating if necessary. How can I make sure that the height of the text view matches that of the truncated content? If, for example, I set the height to a fixed value, there will some variable space at the bottom of the text view which will affect the layout of items below it.
Is there some way to set a desired height, measure the truncated text, and then use that measurement to more precisely adjust the height? Is there even a way to measure the height of the displayed text within the UITextView?
Edit
I need to clarify:
I do not need help truncating the text. As you can see from the screenshot, the text is truncated already.
I cannot measure the text because I would need to measure the the truncated text, which I don't have access to.
The gap at the bottom of the text view is not related to the textcontainerInset.
This is how the screenshot is currently built:
The text is set to some long string.
The text view is artificially constrained to some height, let's say 300. This produces the truncation.
Because 300 is not a precise multiple of the line height, there is some additional space below the last truncated line.
What I would like to do:
After sizing the text view to 300, measure the precise height of the truncated text so that I can then resize the text view a second time to fit it without the additional spacing (e.g. set it to 285 if that is the measured size).
Or, some other method to achieve the same end result.
I expect it's truncated because of your constraints. So you need to calculate the text size in the code and update the constraint value:
let boundingRect = (textView.text as NSString).boundingRect(
with: maxSize,
options: .usesLineFragmentOrigin,
attributes: [ .font: textView.font ],
context: nil
)
heightConstraint.constant = boundingRect.height.rounded(.up)
The result of this operation is float and not related to pixels. When the view size is calculated by the constraints, it get's rounded to pixels (0.5 or 0.333...), that's why we need to round it by ourself to exclude unpredictable cases. To get pixel perfect height you can round it according to screen scale:
textViewHeightConstraint.constant = (boundingRect.height * UIScreen.main.nativeScale).rounded(.up) / UIScreen.main.nativeScale
Also, as #nghiahoang mentioned below, don't forget to zero the insets
textView.textContainerInset = .zero
Here's my sample project
Compile the solution of Philip and set the inset.bottom to 0
textView.textContainerInset.bottom = 0
Directly, it is not possible. If you want to do it, you have take UILabel behind the UITextView. Because UILabel has the property to auto extend the height and width based on text. Now. set equal constraints of UILabel to UItextview.
what should be constraints, let me explore step by step :
set leading and trailing of UILabel.
Fix top constraints of uILabel.
you not need to set height constraint but if you want, you can set greater than equal to constraint of constant 20 or 30.
Now set leading, trailing,top and height constraints of UITextview equal to UILabel.
Now whatever you set text in UIlabel , give it to label as well. I did not in past. If you will find any issue please ask in comment

UILabel wrapping incorrectly in a UICollectionView

Here I have a UICollectionViewCell, with a UILabel. My labels are character wrapping long words onto a second line. I thought autoshrink would take precedence over line breaks, since "Cappuccino" can easily be autoshrunk onto just 1 line. I even have Word Wrap on.
Why is this label being character wrapped as opposed to autoshrunk with a minimum font size?
EDIT: I'm aware that numberOfLines needs to be > 0, but programmatically determining numberOfLines based on a label's text and bounding rect doesn't consider autoshrink. I can check if the font size with 1 line != my desired font size, and adjust numberOfLines by guessing, but there's no isTruncated property for me to tell whether the line has broken. So the right question is, how can I programmatically account for autoshrink while determining an appropriate numberOfLines?
you must set a number of lignes > 0 when using this config for all UI text containers.

How to vertically center text in UILabel with programmatic constraints after height constraint addition

I have a UILabel that I'm using inside a container view. I'm using AutoLayout entirely programmatically--no xib or storyboard. My UILabel constraints (no height constraint set, large fixed width, top and left edges pinned, numberOfLines = 0, bottom of superview pinned to bottom of label) work perfectly for normal (around 13 or 14 point) sized text, but at large (60 point) size text I started noticing large gaps of extra space above and below my character; in this case, the capital letter "S" that's an NSMutableAttributedString. The only attributes for this attributed string are the font name and a kerning value of 1.0. Below picture shows a magnified screenshot of my label from Pixie (white square shown is from that program) with my UILabel's backgroundColor in red:
After doing lots of research (Ignore Ascender and Descender when centering UILabel vertically?, iOS - Get the "real" height of a letter, Vertically center text in UILabel depending on actual visible letter height), it seemed the reason I was encountering this issue was because of the ascender and descender values for this font aren't getting used in this case (this is a capital "S," so it would seem I just need its capHeight value). So, I decided to constrict my label height to this value, and did so by setting a height constraint equal to its capHeight value after the "S" attributed text is set. Doing this produced the following image:
As you can see, the text is now clipped in the label. As a sort of hack, I figured I'd add some padding to counteract this, so multiplying my capHeight value by 1.1 yielded the following image:
That's fine for some padding, but now there's 4 px of extra space at the top. Granted I'm zoomed in very far, but I'm not sure why I'm seeing this—I would think that since the height constraint is set to the height of this capHeight value (which has some extra added for padding now) that the "S" would be vertically centered. I've tried calling setNeedsLayout on the label, but that didn't do anything. These are the things I would love to know:
Why is the capHeight value either not returning the correct value and/or setting the label's height constraint to this value is causing the text to get clipped?
Why do I need to add padding to the capHeight value?
Does anyone have any suggestions on how I can get this text vertically centered after I add padding and/or why it's not happening automatically? I saw this answer (https://stackoverflow.com/a/17376146/482557) but wasn't sure if that would apply here.
Thanks!

UILabel text is not displaying properly

I want to show the text in uilabel. The text is ,000124520.061112782.,3299985343, I have assign line break mode to character wrap and number of lines to 0. But in label first line is displayed only the , and then other characters are displayed in next line. But i want to display the text in two lines only. But it is displayed in three lines. I don't know why , is displayed in first line. Please anyone help me.
You should set the numberOfLines of your UILabel to 1.
When the numberOfLines property of a UILabel is set to 0 the UILabel will render its text over as many lines as it needs - e.g. its infinite. To fix your text to a single line you should therefore set the property to 1.
Obviously your text may not all fit on a single line so you should also set the UILabel's minimumScaleFactor property to allow the UILabel to adjust its font size downward (to the supplied limit) to fit the content into the frame of the label. You will also need to set the UILabel's adjustsFontSizeToFitWidth property to YES.
Further to the above an easy way to calculate the value for the minimumScaleFactor property is to divide the minimum font size by the maximum font size. So, say for example your label's default font size was 12 and you were happy for it to drop to 10, then assign the minimum scale factor as follows:
myLabel.minimumScaleFactor = 10/12.0f;

UILabel AutoResize cuts off the top part of the text

I have a UILabel which autoresizes along with its parent view. The label has AdjustsFontSizeToWidth turned on and has a minimum text size of 0 - so basically it tries to fit all the text into whatever size the UILabel is.
The problem I am having is that vertically the text gets cut off. So yes, the label is adjusting its font size to the width of the label but the text is too tall for the label and thus some of the text is getting cut off.
Is there anyway to work around this so that all of the text, the full height and full width are shown?
I attach an image to show what I mean. The red box is the parent view, the purple box is the UILabel.
Thanks for your help.
What you are adjusting automatically is the Width and not the Height. The Height is something you'll have to adjust manually based on the maximum font size you will use. If the maximum (assigned initial) font size fits in height, so will the smaller one's do, after they are automatically adjusted
I suspect that Lefteris is right, that minimum text size focuses on font size for the width of the control. Note, though, if you want it to resize the font to fit, you want a non-zero minFontSize. See minimizeFontSize notes. Also check out the various NSString UIKit Additions that can be used to get the size of the control necessary to fit your text, and programmatically adjust the size (i.e. the frame) your UILabel accordingly.
In my case there was a bogus vertical centering of a view under the labels being clipped and squashed. That somehow took priority over compression resistance priority of 1000 for the labels. No warning on console about conflict though. But the view debugger was of some help.

Resources