Custom Fonts on iOS

March 19, 2017

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:

Example screenshot showing a variety of custom fonts

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 .ttf or .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:

Example project directory structure with fonts

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.

Adding a folder as folder reference in Xcode

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.)

Checking the Copy Bundle Resources build phase

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 Info.plist.

Add the 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.

Finding the postscript name of a font

Next Time

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.