NSString boundingRectWithSize returning unnecessarily tall height

前端 未结 4 1467
盖世英雄少女心
盖世英雄少女心 2021-01-30 18:12

When using [NSString boundingRectWithSize:options:attributes] the size of the rect that is returned is taller than I would expect for certain strings. The height re

4条回答
  •  北海茫月
    2021-01-30 18:49

    @omz still gets credit for making this work for me. His answer made me look around CoreText some more since I assume something like boundingRectWithSize ultimately calls a CoreText function.

    In Session 226 from WWDC 2012 there was an entire section devoted to calculating the metrics of a line and, to my surprise, they talked about a new CoreText function called CTLineGetBoundsWithOptions.

    As far as I can tell, that method is only documented in CTLine.h and in the CoreText Changes document. It certainly doesn't come up (for me) when doing a normal search in the documentation.

    But it appears to work and in my testing it returns the exact same result as boundingRectWithSize for all the fonts installed on my system. Even better, is that it appears to be almost 2x faster than boundingRectWithSize.

    As the WWDC video mentions, it's a bit obscure why you'd need to calculate the bounds of a string without taking things like line height into account, but if you do need to do that, then I think this might be the best method to use. As always, YMMV.

    Rough sample code:

    NSFont *font = [NSFont systemFontOfSize:13.0];
    NSDictionary *attributes = @{(__bridge NSString *)kCTFontAttributeName : font};
    NSAttributedString *attributeString = [[NSAttributedString alloc] initWithString:self.text attributes:attributes];
    
    CTLineRef line = CTLineCreateWithAttributedString((__bridge CFAttributedStringRef)attributeString);
    CGRect bounds = CTLineGetBoundsWithOptions(line, kCTLineBoundsUseGlyphPathBounds);
    
    CFRelease(line);
    
    return NSRectFromCGRect(bounds);
    

提交回复
热议问题