7

I have a circumstance in my app whereby a label may be given a font size greater than it's height. This is to do with some rather complex architecture and layout code. Normally I would increase the label's height to accommodate the larger font but that is profoundly difficult to do in my scenario and I would rather avoid it.

The next logical thing is to turn clipsToBounds off, to allow the text sublayer to overflow the bounds of the label. Unfortunately this seems to have no effect in this case as the text is still clipped.

Am I missing something?

Jacob King
  • 6,025
  • 4
  • 27
  • 45
  • How about increasing the label's content compression resistance priority? – Dariusz Bukowski Oct 18 '17 at 08:45
  • You may also need to check that `label.layer.maskToBounds = false` also – Wez Oct 18 '17 at 08:46
  • What is the desired behavior? – Hexfire Oct 18 '17 at 08:46
  • 1
    @Wez I can confirm that it is, additionally, the view debugger verifies that both are false at runtime. – Jacob King Oct 18 '17 at 08:47
  • @Hexfire The goal is for the label not to clip the bottom of it's text off. Say for example I have a label of 15pt height, and a font of size 30pt. Only the top 15pts of the text would be visible as the label clips the bottom half. I would like this clipping to not occur, as I would have expected from `masksToBounds = false`. – Jacob King Oct 18 '17 at 08:49
  • @DariuszBukowski Unfortunately that doesn't have an effect. – Jacob King Oct 18 '17 at 08:49
  • @JacobKing do you want to [chat](https://chat.stackoverflow.com/rooms/26424/iosandroidchaosoverflow) about it? – Wez Oct 18 '17 at 08:50
  • You could add another UILabel constrained to the centerY of the first with equalWidth and no height constraint. That way this label would be in the same position but would just expand to hold the text. You'd then just need a little logic to determine which label to show based on line height? – Mike Atkins-Spelling Oct 18 '17 at 08:58
  • Try with using Size To Fix Content of Label? – Scott.N Oct 18 '17 at 09:01

3 Answers3

1

Looking at the documentation for UILabel:

https://developer.apple.com/documentation/uikit/uilabel/1620545-textrect

I think you need to override the method textRect(forBounds:limitedToNumberOfLines:) by explicitly increasing the rectangle returned by this method to the containing size of the label’s string rather than the bounds of the label.

(This solution does of course require you to subclass.)

Hope that helps.

Marcus
  • 2,153
  • 2
  • 13
  • 21
  • That's an interesting idea, I'll give it a try! – Jacob King Oct 18 '17 at 09:03
  • Shoot, so annoyingly I don't have the facility to subclass the UILabel object due to the fact I am using AsyncDisplayKit and the label is wrapped in a ASTextNode with an abstract view. – Jacob King Oct 18 '17 at 09:12
0

You should be able to get the font height from font.lineHeight and then reduce the font size until the line height is less than the label height.

Vince O'Sullivan
  • 2,611
  • 32
  • 45
  • The issue is, Vince, that I don't want to reduce my font height. I want to font to be large it's more a case of I would want to increase the label height to accommodate it. As I said in my question, in my circumstance this is hard to do. Hence looking for a layer clipping based solution. – Jacob King Oct 18 '17 at 08:56
  • Ah, I saw that you didn't want to increase the label size but didn't see that you also didn't want to decrease the font size. One other possibility might be to have a second label centred over the existing label that takes the text and resizes appropriately. In that way, the original label just becomes a place holder in the screen layout. (As mentioned above.) – Vince O'Sullivan Oct 18 '17 at 09:03
0

The reason (need citation) is that UILabel which is embeeded in UIButton cares extra glyph information embedded in font whereas an independent UILabel doesn't.

Solution

You can nest a separate UILabel on top of your UIButton and it will solve the problem. It's ugly but it works. There are few workarounds that you ought to try.

Workarounds

Depending on the scenario here is a small checklist that I found as accepted answer or useful for someone.

1) If you're using a UIButton Make sure you're using this method

[button setTitle forState:]

otherwise you'd need to use the following code to refresh the state

[myButton setNeedsLayout];

2) You might need to adjust your font size to fit the width of the label.

[yourLabel setAdjustsFontSizeToFitWidth:YES];

3) Although setting clipToBounds works in consecutive hierarchy, You might want not want to set individually on either Button or Label.

[yourButton setClipsToBounds:NO];
[yourButton.titleLabel setClipToBounds:NO];

There are few solutions that are pointing UIButton subclassing method which are essentially trying to add UIEdgeInset to button.

Naveed Abbas
  • 1,157
  • 1
  • 14
  • 37