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
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];
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);
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)
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,
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]
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.