UILabel with NSAttributedString is clipping content
Asked Answered
D

5

12

I've got a UILabel set up with auto layout in such a way that its height is based on its intrinsic content size, such that it gets taller when there are more lines in it. I need it to be centered alongside other elements in the same view. With everything default, it works just fine.

However, I'm using a custom font that has a bit too much space in it. I've set up an NSMutableParagraphStyle, like so:

NSMutableParagraphStyle *headlineParagraphStyle = [NSMutableParagraphStyle new];
headlineParagraphStyle.lineSpacing = 0.0f;
headlineParagraphStyle.maximumLineHeight = 20.0f;
headlineParagraphStyle.hyphenationFactor = 0.0f;
headlineParagraphStyle.alignment = NSTextAlignmentLeft;

I'm then creating and setting an NSAttributedString as the UILabel's -attributedText:

NSString *uppercaseHeadline = self.currentStory.headline.uppercaseString;
NSAttributedString *attributedHeadline = [[NSAttributedString alloc] initWithString:uppercaseHeadline attributes:@{NSParagraphStyleAttributeName: headlineParagraphStyle}];
self.headlineLabel.attributedText = attributedHeadline;

The result is that the text looks okay, but it's shoved up above the top of the UILabel and clipped off at the top, while there's still extra space at the bottom of the label:UILabel Clipping

This also throws off the centering of other items against the text in this label, since you can see that the space between the two lines does not line up with the center of the label's frame.

How can I tell UILabel to recenter this text, so that the top doesn't clip and there isn't any space at the bottom?

Devolve answered 8/9, 2013 at 20:17 Comment(0)
D
3

I've realized I never came back and answered this question after iOS 7 was released and the NDA on that platform lifted. As of iOS SDK 7.0, it is possible to use the NSAttributedString attribute NSBaselineOffsetAttributeName, which did exactly what I needed to do.

It was available but "no longer supported" in iOS 6. However, when building with the iOS 7 SDK, it appeared to do the right thing.

Edit: In case it's unclear, I don't recommend doing this. If Apple says it's no longer supported, it's probably not a good idea to rely on it. It worked for me, but it's definitely not a long-term solution.

Devolve answered 4/5, 2014 at 5:38 Comment(0)
J
3

I just had a wild ride with this. For whatever reason, using lineHeightMultiple, maximumLineHeight, and/or minimumLineHeight blows the offset like this.

However, using lineSpacing (which is not an absolute value but a relative value) will change the spacing between lines without messing up the offset.

Jansson answered 30/6, 2015 at 19:27 Comment(0)
M
3

In iOS 10, my solution was to only set maximumLineHeight and to NOT set minimumLineHeight (otherwise, the top of the label gets clipped). Changing lineSpacing or lineHeightMultiple did not help.

Marqueritemarques answered 26/5, 2017 at 2:33 Comment(1)
there's an issue with setting both minimumLineHeight and maximumLineHeight at the same time on iOS 10, but this seems to have been resolved in iOS 11Rothwell
I
2

I feel it's important to link to the 'bizarre interview': http://i.imgur.com/pFeqPHd.gif.

You may need to edit the font's ascender property, see here: UIButton custom font vertical alignment

Ilk answered 9/9, 2013 at 2:23 Comment(1)
I never managed to get this to work. Adjusting the font's ascender and descender properties seemed to have no effect on the final rendering.Devolve
L
0

in my case numberOfLines = 0 was needed otherwise, counterintuitively, line after the newline were clipped

Lamere answered 7/10, 2021 at 13:44 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.