Line Spacing for UILabel with a single line of text - ios

Is it expected that a multi-line UILabel with a custom lineSpacing attribute include that line spacing even when the label's text fits on one line?
Here is my label:
let label = UILabel()
label.numberOfLines = 4
var paragraph = NSMutableParagraphStyle()
paragraph.lineSpacing = 5
paragraph.lineBreakMode = .ByTruncatingTail
label.attributedText = NSAttributedString(string: "Some short text", attributes: [NSParagraphStyleAttributeName: paragraph])
And here is how it is laid out. Note the additional spacing below the text.
For comparison:
What's strange is the lack of consistency. When the label extends to a second line, the bottom line no longer includes this additional spacing:
Is there a way to remove this line spacing when there is a single line of text? Or some other way to enforce some consistency so I can at least account for it?
Update
The baseline calculation also seems broken. When attempting to align a view (here, the red box) with the label's baseline, multi-line labels are partially covered.

Since you said you were using a custom font, my best guess based on prior experience is that the root cause of that issue that you seeing lies somewhere inside of the custom font itself. Whenever I am given a custom font by a client, 90% of the time, something is "wrong" with the actual font metrics (as interpreted by Apple's internal font rendering subsystem, even though it might render correctly somewhere else).
The good news is that this is fixable, but it requires rebuilding the font with new metrics, which is usually a trial/error affair. You might also need to check to see if the license you have for the font will allow such a thing (if it even matters).
That being said, these are some resources to questions that I keep around for this exact scenario whenever I start a new project:
Here's a similar question to yours with the assumption that this is a custom font issue: "Custom UIFont baseline shifted". This question deals with this issue in a UIButton "UIButton custom font vertical alignment", but both of these questions end up at the answer to this question "Custom installed font not displayed correctly in UILabel".
I have a personal testbed app for custom fonts now that I use whenever I am first given a custom font. This allows me to test the font in isolation for each rebuild iteration to make sure it's perfectly rendering. Make sure to test your changes in various font sizes and even in additional languages (yes, lots of permutations). I have had issues specifically with Thai and Chinese when using custom fonts as their ascenders extend very close to the edge of the bounding box for a UILabel. The testbed that I've created for myself includes the font rendered in basic UILabels in various sizes and various languages in various sizes (since like I said, I've had a bad experience in the past with custom fonts in certain languages that rendered fine in Roman characters).
If someone has a better solution to this, I'd love to hear it as I run into this issue with custom fonts almost every time. This is my workflow for nipping the issue in the bud before we start compensating for the font's rendering issues during layout or using individual attributed string adjustments. I'm not font expert, I'm just a guy who likes fonts to render like the built-in fonts (especially when using auto layout).

You can calculate the number of lines and set lineSpacing to 0 if there's only one line.
But there might be a better solution.

paragraphStyle.lineBreakMode = NSLineBreakByCharWrapping
can avoid this issue when text is multiline.
explicitly setting the font with with fontName [UIFont fontWithName:#"PingFangSC-Regular" size:14] , instead of using [UIFont systemFontOfSize:14] can avoid the issue when text is single line.
Hope this is helpful for you!

This is def. a issue for UILabel. It happens for custom as well as the system fonts.
If you can use a UITextView, go with that. The UITextView has no problems with single or multi line text line-spacing and behaves correctly (single line = no line spacing).
This way you can also avoid creating a custom line count func/ext.

Yes, the lineSpacing is applied regardless of how many lines are in the label. If you're using autolayout, you can work around this by constraining your label's baseline to its parent or sibling views (as appropriate), instead of the label's top edge aligned to the parent or sibling's top. (This assumes, however, that your label's background color is the same as the color of its parent view; otherwise, you'll see the extra line spacing appear in the background color.
Another thing you can do (and this is probably preferable, now that I think about it) is to set a paragraphSpacing attribute of 0 as well. That should negate the lineSpacing for the last line in the label, regardless of how many lines you have.

Related

iOS Autoshrink not working on single word in UILabel

Using autolayout to have a multiline UILabel auto size the text to fit does not work for single words.
Here is how storyboard is set up:
Here's the problem.
This does not display properly:
But this does:
I have adjusted every setting in the storyboard. I have changed all of the Line Break settings (wrap, truncate, etc), I have adjusted # of lines, I have made text plain vs attributed, I've changed font sizing and scaling, everything. What am I missing? Why does "California" get cut off instead of shrinking to fit? I've seen many other posts on SO and haven't yet found a solution (which needs to be compatible back to iOS 9)
Your label is being filled both horizontally and vertically until it runs out of space, then it starts shrinking the text to fit. In the one word example it breaks the word into two lines because there is vertical room.
Do you know in advance or can you calculate in the app when you have only one word in this label? If so you can change the number of lines to 1 instead of 0 so the app will keep the contents on one line and shrink this word.

UILabel alignment right issue

I have a problem with UILabel in Swift. Problem happens when text is changed often (like a time readout) in the label.
With alignment left everything works perfect. But I need alignment right.
And in this mode text jumps left and right when changed. This jump is about 1 pixel.
May be someone know how to solve this problem?
Based on the code in your comment:
label.font = label.font.withSize(12)
You are using the standard iOS system font, which is not monospaced, and therefore will cause spacing issues when the text changes. If you use a monospaced font (Courier, Menlo, etc), this issue will go away.
Alternatively, you could handle the drawing of the text yourself or adjust the font's kerning.

Autoshrink in UILabel only for width?

I have some ASCII syntax diagrams which must not have line breaks in the middle.
These don't have to be editable so I thought the best way is to use an UILabel with auto shrink option. But this option shrinks the text also if the content doesn't fit the height of the labels frame rectangle.
I just want to shrink only if the content doesn't fit the width. It would be absolutely fine to scroll vertically through the text.
What is the best way to do this with UILabel or any other UI element?
Use UITextView with 'editable' property set to false.
So let me rephrase your question. I guess what you want is a UILabel which can show multiple lines, but the longest line need to fit into the width of UILabel. If this is what you want, well the imagination is weird to me...
But anyway, I feel there's a conflict in your settings. First, allowing multiple lines implies you set "Lines" attribute (number of lines) as 0, which allows unlimited lines. But then Autoshrink will play no effect. I'm afraid it is not possible to be done by just setting the storyboard and instead, you need to write some code.
I guess people have raised related questions earlier, by which they want to dynamically change the font size when the text become too long. I guess you want to take a look about this:
Autoshrink on a UILabel with multiple lines
The last issue is you also want the scrolling effect (this is why I feel the outlooking will be weird.) But in short, to achieve this you need 1) dynamically change the UILabel height, most likely using the same technique as explained in the reference thread, and 2) wrap the UILabel in a scroll view. Maybe this can achieve what you want.

Xcode Label with long Text not properly shown

This is my first IOS app, just for training, and I got some issue with Label ,check the image
As you can See Object: Photo- Visualizing the Thomas Walther is not properly shown and some words are missing.
So How to fix it and make the string appears on multiLines if it's too long?
In your storyboard, select the UILabel and open the Attributes Inspector (in the utilities, which can be opened with the shortcut opt-command-4). You can change all the the basic properties of the UILabel here.
For multiple lines, ensure that the label height is large enough and set the Lines to 0. You can also change the font scaling in the Autoshrink property (default is fixed font size).
I can't really tell from your screenshot, but you may have some Auto Layout issues with the width of your label to the right side of the window. So you may want to look into setting Auto Layout constraints as well.

IOS: uilabel cut my word

I have a problem with label and I don't understand where is the solution.
I set my label with "Word Wrap" and 3 lines but it cut a word when text wrap...why??
thanks
Probably bounds are too small? Stretch the UILabel out as much as possible (height-wise), set lines to 999 and see if it still cuts it.
edit: Somehow this still gets views. More recent versions of iOS no longer have as many issues with UILabel, so this no longer applies. (especially with Auto Layout)
This is a really common problem when trying to use multi-line UILabels. The short answer is to use a UITextField instead if you want multiple lines of text. You get more control over the padding around the text as a bonus.
(yes, you can 'fix' the UILabel but sometimes simpler solutions are better)

Resources