Practical Dynamic Type

Chris Sessions
Oct 27, 2017 · 4 min read

One of my favorite WWDC talks this year was Building Apps with Dynamic Type. It presents a number of really nice improvements in iOS 11 for building accessible apps for low vision users.

In particular, the talk features a demo with custom fonts that scale dynamically with adjustments to the iOS system text size. Previously this was only possible by observing UIContentSizeCategoryDidChange and manually re-rendering views whenever something changed.

Having dealt with this problem recently, I imagined tearing out obsolete observers, and replacing hacky workarounds with something simple and elegant. Sadly, I faced a couple obstacles to the golden path presented in the talk.

The first is that I’ll need to support iOS 10 for a good while longer, and it only provides half of what’s required for dynamically scaling custom fonts. The two essential ingredients are:

  1. adjustsFontForContentSizeCategory, available as of iOS 10, and
  2. UIFontMetrics, only available in iOS 11.

The second obstacle is a little more nuanced. After looking at Apple’s Human Interface Guidelines on Typography I asked our design team whether it’d make sense to use Apple’s Dynamic Type styles as a foundation for their typography specs.

As it turns out, they have a number of reasons for bypassing Apple’s standard. In some cases, clients want a more extensive range of styles. More often, we’re building apps for both iOS and Android where the designers must strike balance between the iOS look and feel, and Android’s Material Design Spec. Very rarely would the Dynamic Type styles mesh with what our designers are trying to accomplish.

Well then… now what?

I set about chipping away at my dynamically scaling custom font problem. For apps that support iOS 10, we have adjustsFontForContentSizeCategory, but not UIFontMetrics. A wrapper for the latter seems like a good first step.

A UIFontMetrics wrapper

FontMetrics wraps a subset of UIFontMetrics. Pass in a font or a value, and get back a copy that is scaled up or down based on the device’s current UIContentSizeCategory.

What’s the difference between UIFontMetrics scaling and calculating it manually? Fonts that have been scaled using UIFontMetrics don’t require any further work to scale up and down when a device’s Dynamic Type settings change. In iOS 10 and earlier, text displays at the correct scaled size when it first appears in a view — but you need to observe and manually redraw the view if the UIContentSizeCategory changes.

Whether it’s critical to scale text dynamically depends. Adjusting the device text size and watching how an app responds is probably more of a software developer behavior than a real world one. But if you want this functionality to work correctly for your iOS 10 users, you’ll still need to include UIContentSizeCategoryDidChange observers for now.

Some helpful factories

First, however, let’s write some UIFont factories, that ensure we use FontMetrics.scaledFont(for:) by default when grabbing a font.

Easy enough. We can use the text point size specified in our designs, and by default they’ll appear scaled up or down based on the device settings.

Now on to our UILabel factories:

On a little bit of a side note, I’ve recently taken the Nibless Challenge, and so far I love it. Besides eliminating the general nib weirdness from my projects, it seems to be helping with accessible UI. Perhaps it’s because constraints are more rare and deliberate now, and aren’t lost in an ocean of XML.

The UILabel factories above, and similar helpers, allow rapid UI building that could look something like this:

Summary

Further Resources

Using A Custom Font With Dynamic Type and Auto Adjusting Fonts for Dynamic Type from Use Your Loaf.

Livefront

Thoughts from the Livefront team

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store