Damn custom fonts (iOS), again!

I’ve gone through a rough patch lately while working on my text editor and another very-small-app-in-a-day (which is taking me way too long, but almost done in 48 hours). The culprit: custom fonts. The loss: one hour. There’s been a change in how we manage custom fonts in Xcode, which I did not have the occasion to witness earlier. Googling it did not solve the issue, so hopefully it will save someone some time.

Adding custom Fonts to your project

Custom fonts for your UITextView or UITextField has been available for a long time, since the iPhone SDK 3.2 if I remember well. The syntax for invoking them is very simple:

[textView setFont:[UIFont fontWithName:myGreatFontStringName size:myGreatFontFloatSize];

The tricky part is actually getting the font into your project. I have used a quick tuto from TetonTechnical, which has been up for 2 years. For completeness, Here are the steps (without the images):

  • drag your font into your project tree, with the “copy” ticked. I’ve used ttf and otf without a problem,
  • declare the fonts in the app’s PList file, as “Fonts provided by application”. You are declaring them here with the full file name, eg. “Cantarell.ttf” or “Goudy Bookletter 1911.otf” in my case.
  • open Font Book, and check the name of the font as it is given there. This is the NSString you are going to pass as argument to fontWithName. So, in my case, I’ve got
@"Cantarell"

and

@"Goudy Bookletter 1911"

all very simple, though the names can be much trickier to catch, see the gist below to enumerate all the fonts as seen by iOS.

Now, here lies the rub. In previous versions of Xcode, that’s all you had to do. But in the version I’m working in today, the fonts did not appear to be loaded. The reason? That b%tch was not included in the Target Membership as being part of the package. Very simple way to change this: with the font file selected in your project tree, show the utilities panel (that’s the panel on the right of Xcode by default), scroll down to “Target Membership”, and tick your product there. It should be something like this:

Font screen shot

(I’ve blurred the name of the project, it’s still secret and a bit shameful ;-).

Bonus: gist to output all the fonts available to your console

for (id objFamilyName in [UIFont familyNames]) {
    if ([objFamilyName isKindOfClass:[NSString class]]) {
        for(id objFontName in [UIFont fontNamesForFamilyName:(NSString*)objFamilyName]) {
            if ([objFontName isKindOfClass:[NSString class]]) {
                NSLog(@"%s: %@: %@", __FUNCTION__, objFamilyName, objFontName); 
            }
        }
    }
}