问题
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 Documents folder
CGDataProviderRef fontDataProvider = CGDataProviderCreateWithFilename([fontPath UTF8String]);
CGFontRef customFont = CGFontCreateWithDataProvider(fontDataProvider);
CGDataProviderRelease(fontDataProvider);
How can I convert the CGFontRef
to a UIFont
to be used in [UILabel setFont:]
?
回答1:
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]
回答2:
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];
回答3:
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.
回答4:
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);
回答5:
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,
回答6:
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)
来源:https://stackoverflow.com/questions/9205709/how-to-convert-cgfontref-to-uifont