Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scaling font size to fit vertically in UILabel

I want to take a standard UILabel and increase the font size so that it fills the vertical space. Taking inspiration from the accepted answer for this question, I defined a subclass on UILabel with this drawRect implementation:

- (void)drawRect:(CGRect)rect
{
    // Size required to render string
    CGSize size = [self.text sizeWithFont:self.font];

    // For current font point size, calculate points per pixel
    float pointsPerPixel = size.height / self.font.pointSize;

    // Scale up point size for the height of the label
    float desiredPointSize = rect.size.height * pointsPerPixel;

    // Create and assign new UIFont with desired point Size
    UIFont *newFont = [UIFont fontWithName:self.font.fontName size:desiredPointSize];
    self.font = newFont;

    // Call super
    [super drawRect:rect];
}

But this doesn't work as it scales the font beyond the bottom of the label. If you want to replicate this, I started with a label 289x122 (w x h), Helvetica as the font and a starting pointSize of 60 which fits comfortably in the label. Here is example output from the standard UILabel and my subclass using the string "{Hg":

uilabel

uilabel subclass

I've looked at font descenders and ascenders, tried scaling taking these into account in different combinations, but still haven't had any luck. Any ideas, is this something to do with different fonts having varying descender and ascender lengths?

like image 418
user524261 Avatar asked Dec 01 '12 21:12

user524261


1 Answers

Your calculation for pointsPerPixel is the wrong way up, it should be...

float pointsPerPixel =  self.font.pointSize / size.height;

Also, maybe this code should be in layoutSubviews as the only time the font should be changed is when the frame size changes.

like image 180
combinatorial Avatar answered Nov 08 '22 14:11

combinatorial