Cocoatype
Cocoatype

Reputation: 2571

UILabel with NSAttributedString is clipping content

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?

Upvotes: 12

Views: 4139

Answers (5)

Anton Tropashko
Anton Tropashko

Reputation: 5806

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

Upvotes: 0

lifjoy
lifjoy

Reputation: 2188

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.

Upvotes: 3

puzzl
puzzl

Reputation: 831

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.

Upvotes: 3

Cocoatype
Cocoatype

Reputation: 2571

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.

Upvotes: 3

Graham Perks
Graham Perks

Reputation: 23390

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

Upvotes: 2

Related Questions