iosxcodecatextlayer

CATextlayer change size of FONT to fit the frame


I have a CATextlayer of a certain size and NSAttributedString text of unknown length.

I need to adjust the font-size so the text fits the frame (not vice versa :)

Any ideas where to start? :)

[Edit] as nall points out, I can determine the string length, of course, it's some text entered by the user that I need to fit into a box of fixed size.


Solution

  • I ended up doing this:

    textlayer is a CATextlayer

    theString is a NSMutableAttributedString

    And yes, it's not very elegant and could definitely be improved ;)

    CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString((__bridge CFAttributedStringRef)theString);
    
        CGRect columnRect = CGRectMake(0, 0 , 320, 150);
    
        CGMutablePathRef path = CGPathCreateMutable();
        CGPathAddRect(path, NULL, columnRect);
    
        CTFrameRef frame = CTFramesetterCreateFrame(framesetter, CFRangeMake(0, 0), path, NULL);
    
        CFRange frameRange = CTFrameGetVisibleStringRange(frame); 
    
        int fontSize = 18;
    
        while(theString.string.length > frameRange.length){
    
            fontSize--;
    
            CFStringRef fontName = (__bridge CFStringRef)[defs objectForKey:@"font"];
    
            CTFontRef font = CTFontCreateWithName(fontName, fontSize, NULL);
    
            [theString addAttribute:(NSString *)kCTFontAttributeName
                              value:(__bridge id)font
                              range:NSMakeRange(0, theString.string.length)];
    
            CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString((__bridge CFAttributedStringRef)theString);
    
            CGRect columnRect = CGRectMake(0, 0 , 320, 150);
    
            CGMutablePathRef path = CGPathCreateMutable();
            CGPathAddRect(path, NULL, columnRect);
    
            CTFrameRef frame = CTFramesetterCreateFrame(framesetter, CFRangeMake(0, 0), path, NULL);
    
            frameRange = CTFrameGetVisibleStringRange(frame); 
    
            textLayer.string = theString;
        }