How to convert CGFontRef to UIFont?

后端 未结 6 1506
礼貌的吻别
礼貌的吻别 2020-12-03 03:57

I want to use a custom font for a UILabel. The custom font is loaded by from a file:

NSString *fontPath = ... ; // a TTF file in iPhone Document         


        
相关标签:
6条回答
  • 2020-12-03 04:00

    You can't convert CGFontRef to UIFont directly but you can register CGFontRef using CTFontManagerRegisterGraphicsFont and then create corresponding UIFont.

    NSString* fpath = [documentsDirectory stringByAppendingPathComponent:@"custom_font_file_name.ttf"];
    CGDataProviderRef fontDataProvider = CGDataProviderCreateWithFilename([fpath UTF8String]);
    CGFontRef customFont = CGFontCreateWithDataProvider(fontDataProvider);
    CGDataProviderRelease(fontDataProvider);
    NSString *fontName = (__bridge NSString *)CGFontCopyFullName(customFont);
    CFErrorRef error;
    CTFontManagerRegisterGraphicsFont(customFont, &error);
    CGFontRelease(customFont);
    UIFont* uifont = [UIFont fontWithName:fontName size:12];
    
    0 讨论(0)
  • 2020-12-03 04:03

    CTFontRef and UIFont are toll-free bridged, so you can turn your CGFont into a CTFont and then turn that into a UIFont:

    CTFontRef ctFont = CTFontCreateWithGraphicsFont(cgFont, pointSize, NULL, NULL);
    UIFont *uiFont = CFBridgingRelease(ctFont);
    
    0 讨论(0)
  • 2020-12-03 04:07

    Updated for Swift 4 to get PostScript name (where font is the CGFont):

    let fontName = font?.postScriptName as String?
    textLabel.font = UIFont(name: fontName!, size: 17)
    
    0 讨论(0)
  • 2020-12-03 04:10

    You can convert your CGFont to CTFont, but unfortunately neither of those will get you a UIFont. Here are the ways to get a UIFont: ask for a system font, or ask for a font by its PostScript name. Therefore, for custom supplied fonts in a UILabel, I suggest you use the latter.

    If you know the font file your app will use ahead of time you can add it to your bundle and load it with UIFont, +fontWithName:size: as UIFont searches your bundle for a font file with that PostScript name.

    For example, the TrueType font file "VeraMono.ttf" has PostScript name "Bitstream Vera Sans Mono", so it's loaded into a UILabel like:

    label.font = [UIFont fontWithName:@"Bitstream Vera Sans Mono" size:12];

    To get PostScript names non-dynamically, use a font tool, or, in the case above the PostScript name happens to be equal to the "Full Name" display by Finder > Get Info.

    However, for cases where you won't necessarily know the font's PostScript name ahead of time (such as supporting user-defined fonts), perhaps you can load the filename into NSData and "grep" for its PostScript name...

    Good luck,

    0 讨论(0)
  • 2020-12-03 04:14

    Conrad's answer is close but doesn't quite work. You need to provide UIFont with the PostScript name, rather than the full name.

    NSString *fontName = (NSString *)CGFontCopyPostScriptName(fontRef);
    UIFont *font = [UIFont fontWithName:fontName size:someSize]
    
    0 讨论(0)
  • 2020-12-03 04:22

    They are, in principle, not directly convertible. One simple reason is that UIFont encapsulates font size, whereas CGFont is size-independent (with size being a property of the graphics context; see CGContextSetFontSize()).

    Assuming that you have otherwise determined what font size you want, you should be able to something like:

    NSString *fontName = (NSString *)CGFontCopyFullName(someCGFontRef);
    UIFont *font = [UIFont fontWithName:fontName size:someSize];
    [fontName release];
    

    I haven't actually tested this, but it should work (maybe with some minor additions). I believe that there is a correspondence between names for CGFont and UIFont - but if there isn't, this obviously won't work.

    0 讨论(0)
提交回复
热议问题