Custom Fonts on iOS
On one of my side projects, I wanted to experiment with custom fonts while still respecting font size adjustments for accessibility. I’m using storyboards for this project, so also want to be able set font styles there.
Here’s a screenshot of the app in progress:
In this post I’ll share the steps to add custom fonts to an app in Xcode.
Get Licensed Fonts
Like other intellectual property we need a license to use a font in an app. Just because we have the files for a font doesn’t mean we have permission to use the font in our app. There are a variety of fonts available under the Open Font License from Google Fonts. Many foundries and aggregators also offer fonts that can be licensed for in-app use.
For this example, I’ll be using fonts from the Museo family by exljbris. (Full disclosure, I currently have licenses to use these fonts locally and on the web but haven’t bought an app license yet since I’m not close to shipping.)
Add Font Files to Xcode Project
Once we have the
.otf files for our font, the next step is adding them to our Xcode project.
I like to use a separate
Fonts folder in my project structure. This makes it easier to update the shipping fonts in the app. Copy the font files into the folder, like so:
Next drag the
Fonts folder from Finder into the Xcode sidebar under the Resources group for your project. When you drop the folder, Xcode will prompt you whether to create a group or a folder reference. Choose folder reference and you’ll be able to adjust the included fonts in Finder while making minimal changes to the Xcode project.
Also be sure to check the main target for your app so the
Fonts folder and its content will be copied to your app bundle.
Edit Copy Resources Build Phase
Next we’ll double check that Xcode updated the Copy Resources build phase correctly.
In your Xcode project, select your main app target and go to the Build Phases section. Tip open the Copy Bundle Resources build phase. You should see that your new
Fonts folder is in the list. (If it’s missing, click the “+” button at the bottom of the phase and choose the folder from the list.)
Add Info.plist Keys
[Updated, April 4, 2017: You can skip this step! See this follow-up post for the details.]
There’s just one more configuration step before we can start using our custom fonts. We have to tell iOS about the fonts by editing the app’s
UIAppFonts key with an array of strings as the value. Each string should be the relative path to a custom font file in your app bundle. Since we copied the
Fonts folder and its contents, we need to include that in the path.
Here’s what I added to my
Info.plist for the eight font files I’m including in my app:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> … <key>UIAppFonts</key> <array> <string>Fonts/MuseoSans-300.otf</string> <string>Fonts/MuseoSans-500.otf</string> <string>Fonts/MuseoSans-500Italic.otf</string> <string>Fonts/MuseoSans-700.otf</string> <string>Fonts/MuseoSlab-300.otf</string> <string>Fonts/MuseoSlab-300Italic.otf</string> <string>Fonts/MuseoSlab-500.otf</string> <string>Fonts/MuseoSlab-500Italic.otf</string> </array> </dict> </plist>
Using the Custom Fonts
To use a custom font in code we instantiate it by name. For example:
let size: CGFloat = 17 let font = UIFont(name: "MuseoSlab-500", size: size) label.font = font ?? UIFont.systemFont(ofSize: size)
There are two things to watch out for here.
UIFontinitializer is failable, so we have to provide a fallback. In the example above I’m falling back to the system font of the same size.
- The name of the font is not necessarily the font’s file name. Instead, it’s the font’s PostScript name. You can find the PostScript name by double clicking the font file to install it on your Mac. Then launch the FontBook app, find the font, and look at its info pane as shown below.
Getting our fonts into the app bundle and onto the screen is rewarding, but our app isn’t complete if we don’t support accessibility.
In the next post I’ll share an extension on
UIFont that lets us adapt Apple’s
UIFontTextStyles to custom fonts so we can respect our users’ font size adjustments.
I’ll also share an AppearanceManager class with extensions on UIViewController and UIView that let us easily propagate font size changes without any additional code in our individual view controllers and views.