Scaling font size to fit vertically in UILabel

寵の児 提交于 2019-12-02 20:35:20
    12

    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.

    • 1
      well... that's was an embarrassingly simple mistake. Thanks for spotting it. – user524261 Dec 2 '12 at 17:51
    • I tried implementing it in layoutSubviews, but I don't think it works. I think the reason is that assigning a new font to the UILabel subclass triggers another invocation of layoutSubviews, which is problematic. In my implementation, one of my app's queues got locked up. – user444731 Mar 18 '15 at 16:25
    0

    I wonder if its a rounding error inching up to the next larger font size. Could you just scale the rec.size.height slightly? Something like:

    float desiredPointSize = rect.size.height *.90 * pointsPerPixel;
    

    Update: Your pointPerPixel calculation is backwards. You're actually dividing pixels by font points, instead of points by Pixels. Swap those and it works every time. Just for thoroughness, here's the sample code I tested:

    //text to render    
    NSString *soString = [NSString stringWithFormat:@"{Hg"];
    UIFont *soFont = [UIFont fontWithName:@"Helvetica" size:12];
    
    //box to render in
    CGRect rect = soLabel.frame;
    
    //calculate number of pixels used vertically for a given point size. 
    //We assume that pixel-to-point ratio remains constant.
    CGSize size = [soString sizeWithFont:soFont];
    float pointsPerPixel;
    pointsPerPixel = soFont.pointSize / size.height;   //this calc works
    //pointsPerPixel = size.height / soFont.pointSize; //this calc does not work
    
    //now calc which fontsize fits in the label
    float desiredPointSize = rect.size.height * pointsPerPixel;
    UIFont *newFont = [UIFont fontWithName:@"Helvetica" size:desiredPointSize];
    
    //and update the display
    [soLabel setFont:newFont];
    soLabel.text = soString;
    

    That scaled and fit inside the label box for every size I tested, ranging from 40pt to 60pt fonts. When I reversed the calculation, then I saw the same results with the font being too tall for the box.

    • There's no rounding to integers because we're using float pointSize values. Even so, the fontSize is out by more than a whole pointSize. Agreed that you can scale back down by a factor, but this is more of a fudge than an exact calculation and varies by font. – user524261 Dec 2 '12 at 11:56

    Your Answer

    By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

    Not the answer you're looking for? Browse other questions tagged or ask your own question.

    标签
    易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
    该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!