14

I have a list of font names in my app, which are all displayed in the font they represent. The following three do not work though:

ArialRoundedMTBold
ChalkboardSE-Bold
TrebuchetMS-Bold

Instead they display in the standard font.

Any ideas why these might not be showing up?

August Lilleaas
  • 54,010
  • 13
  • 102
  • 111
Andrew
  • 15,935
  • 28
  • 121
  • 203
  • I have a similar problem with Chalkduster not working. I've tried choosing it in IB. I've tried setting the font name in code using every variation of the name I can think of. The font doesn't get used either on my mac or on the phone.I tried dumping a list of font names and Chalkduster doesn't show up. However, it shows up correctly in a "fonts" app that I downloaded. This has me befuddled. – Kevin Lawrence Sep 06 '11 at 21:36
  • I looked into this some more. The list of fonts on iPhone and iPad is not identical. Chalkduster is available for iPad but not iPhone. Chalkboard is available on all versions of iOS on iPhone plus iPad 4.x but not 3.x. Details here: http://www.whatsyourdigitaliq.com/2011/05/11/fonts-available-in-various-versions-of-ios/ – Kevin Lawrence Sep 06 '11 at 21:45

5 Answers5

39

How to configure a custom font

To use a custom font (one not included in iOS) you have to edit your <appname>-Info.plist file and create a new UIAppFonts key with type array, where each element of the array is a String with the name of your font file. Example: VAGRoundedStd-Light.ttf. You also have to add the file to your project.

UIAppFonts

Note: When you type UIAppFonts and press enter, the key is converted to "Fonts provided by application".

However, when you use the font in Interface Builder (or with UIFont) you don't use the filename of the font, but the name that appears when you open the font in the application Font Book of your Mac. For the previous example it would be VAG Rounded Std Light.

Font Book

OS X is more tolerant than iOS digesting TrueType formats, so on rare occasions you may find a font that works in OS X but not in iOS. If that happens, replace the font to see if at least you got the process right.

How to load a font programmatically

This solves the case where the font license requires you to distribute the font encrypted.

  1. First step is to encrypt and decrypt the font with whatever algorithm you see fit.
  2. Load the font as a NSData object and reverse the encryption.
  3. Register the font programmatically.

This following recipe is from Loading iOS fonts dynamically by Marco Arment. It makes the fonts available in UIFont and UIWebView. The same code can be used to load fonts from the Internet.

NSData *inData = /* your decrypted font-file data */;
CFErrorRef error;
CGDataProviderRef provider = CGDataProviderCreateWithCFData((CFDataRef)inData);
CGFontRef font = CGFontCreateWithDataProvider(provider);
if (! CTFontManagerRegisterGraphicsFont(font, &error)) {
    CFStringRef errorDescription = CFErrorCopyDescription(error)
    NSLog(@"Failed to load font: %@", errorDescription);
    CFRelease(errorDescription);
}
CFRelease(font);
CFRelease(provider);

How to load more than two fonts of the same family

This is the case where iOS refuses to load more than two fonts from the same family.

Here is a code workaround from stackoverflow user Evadne Wu. Simply stick the following in your app delegate (note that it uses two frameworks):

#import <CoreText/CoreText.h>
#import <MobileCoreServices/MobileCoreServices.h>

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    CTFontManagerRegisterFontsForURLs((__bridge CFArrayRef)((^{
        NSFileManager *fileManager = [NSFileManager defaultManager];
        NSURL *resourceURL = [[NSBundle mainBundle] resourceURL];
        NSArray *resourceURLs = [fileManager contentsOfDirectoryAtURL:resourceURL includingPropertiesForKeys:nil options:0 error:nil];
        return [resourceURLs filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(NSURL *url, NSDictionary *bindings) {
            CFStringRef pathExtension = (__bridge CFStringRef)[url pathExtension];
            NSArray *allIdentifiers = (__bridge_transfer NSArray *)UTTypeCreateAllIdentifiersForTag(kUTTagClassFilenameExtension, pathExtension, CFSTR("public.font"));
            if (![allIdentifiers count]) {
                return NO;
            }
            CFStringRef utType = (__bridge CFStringRef)[allIdentifiers lastObject];
            return (!CFStringHasPrefix(utType, CFSTR("dyn.")) && UTTypeConformsTo(utType, CFSTR("public.font")));

        }]];
    })()), kCTFontManagerScopeProcess, nil);

    return YES;
}

Available as gist. Commented in the author blog: Loading 2+ fonts on iOS from the same font family.


An alternative, more involved workaround from pixeldock.com:

If you add more than 2 font variants of the same font family (e.g. “Normal”, “Bold” and “Extended”), only the last two font variants that you added to the project will be usable.

If you see this happening, it is a limitation of your SDK version, and the only way out of it is editing the font family with a Font editor like Fontforge. Again, from pixeldock.com:

  1. Open your Font in Fontforge
  2. Goto ‘Element’ -> ‘Font Info’ and change the ‘Family Name’ field
  3. Goto ‘Element’ -> ‘TTF Names’ and change the fields ‘Family’ and ‘Preferred Family’
  4. Goto ‘File’ -> ‘Generate Fonts’ and save your edited font
Community
  • 1
  • 1
Jano
  • 62,815
  • 21
  • 164
  • 192
  • 3
    I wish I could +100.. Thanks a lot Jano.. :) – Yama Feb 16 '12 at 12:03
  • However, when you use the font in Interface Builder (or with UIFont) you don't use the filename of the font, but the name that appears when you open the font in the application Font Book of your Mac. For the previous example it would be VAG Rounded Std Light. OS X is more tolerant than iOS digesting TrueType formats, so on rare occasions you may find a font that works in OS X but not in iOS. If that happens, replace the font to see if at least you got the process right. SAVED MY LIFE !!!!!!!! THANKS – Vassily Mar 22 '12 at 09:22
  • You've just stopped me from breaking my MacBook in half. Thank you! – svintus May 07 '12 at 02:23
  • 2
    I get the error Failed to load font: The operation couldn’t be completed. (com.apple.coretext error 105 - Could not register the CGFont '') – Hiren Apr 10 '13 at 13:01
  • +infinity -- I literally spent the entire day trying to figure this out. You are an absolute lifesaver!!! Thank you so much. – dcgoss Aug 25 '14 at 02:14
2

Only a subset of Mac OS fonts are available in iOS. If you set a font that is not available, it will be displayed as the standard Helvetica.

Matt Wilding
  • 20,115
  • 3
  • 67
  • 95
  • These fonts are available though. They're showing inside a UIPickerView that i have, but not displaying on the other area that they should, despite being quoted as the same font name. And it's just those fonts. – Andrew May 09 '11 at 23:48
  • @Andrew: Does "despite being quoted as the same font name" mean that if you NSLog() the UIFonts of both of the controls in question, they both print out the same font name? – Matt Wilding May 10 '11 at 00:08
  • They both come from the same array. One of them returns as font-family: "Helvetica"; font-weight: normal; font-style: normal;, and one returns as `font-family: "Chalkboard SE"; font-weight: bold; font-style: normal;` – Andrew May 10 '11 at 00:26
1

I was using a Google font named Arvo. It had the following files:

Arvo-Regular.ttf Arvo-Bold.ttf Arvo-BoldItalic.ttf Arvo-Italic.ttf These names were added into my app's info.plist but for some reason, my app could only read the bold, bolditalic, and italic fonts. It couldn't read the regular font when i tried to load it. However, after printing out the font names, it came out that Arvo-Regular was recognized as Arvo in my app.

kevinl
  • 4,194
  • 6
  • 37
  • 55
0

Open Font Book application. If you installed the fonts yourself, go to user, look for the fonts you want and use the PostScript name of the font in your xcode project.

It should work even for different font variations of the same family.

andresousa
  • 81
  • 1
  • 4
  • Not working in UIwebView with javascript. I get the error : FT_Open_Face failed: error 2. I want to use Shruti.ttf – Hiren Apr 11 '13 at 05:18
0

I had a similar issue with not finding Chalkduster - even though IB listed it as a font and it's listed as an IOS font. I discovered that the list of fonts on iPhone and iPad is not identical.

Chalkduster is available for iPad but not iPhone. Chalkboard is available on iPad 4.x but not 3.x. It is available on iPhone 3.x & 4.x.

More details here: http://www.whatsyourdigitaliq.com/2011/05/11/fonts-available-in-various-versions-of-ios/

Kevin Lawrence
  • 698
  • 7
  • 23