---
title: "Practical Dynamic Type"
source: "/writing/practical-dynamic-type/"
---

Article

# Practical Dynamic Type

Chris Sessions

October 27, 2017

One of my favorite WWDC talks this year was [Building Apps with Dynamic Type](https://developer.apple.com/videos/play/wwdc2017/245/) . 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](https://developer.apple.com/ios/human-interface-guidelines/visual-design/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](https://material.io/guidelines/style/typography.html) . Very rarely would the Dynamic Type styles mesh with what our designers are trying to accomplish.

## Well then... now what?

Okay it might not be practical to do things exactly as presented in the forward-looking WWDC talk. Then what, if anything, can we take from it and begin to use right away?

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

Apple describes `[UIFontMetrics](https://developer.apple.com/documentation/uikit/uifontmetrics)` as "a utility object for obtaining custom fonts that scale to support Dynamic Type." I'd previously written something approximating this functionality for an iOS 9 project, and that provided the fallback code I needed for anyone not yet running iOS 11.

`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](https://developer.apple.com/documentation/uikit/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

With `UIFontMetrics` taken care of, what comes next? The other piece that's needed for dynamic custom font scaling is `adjustsFontForContentSizeCategory`. I'd rather not define this all over the place, and if I did it's probably something I'd frequently forget. We'll want some little `UILabel` 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

With the bits of code above, we can begin leveraging iOS 11's Dynamic Type improvements now, even while continuing support for earlier iOS versions. We have the building blocks to offer full accessibility to low vision iOS users, and it now takes minimal additional effort on our part.

## Further Resources

[Building Apps with Dynamic Type](https://developer.apple.com/videos/play/wwdc2017/245/) from Apple WWDC 2017.

[Using A Custom Font With Dynamic Type](https://useyourloaf.com/blog/using-a-custom-font-with-dynamic-type/) and [Auto Adjusting Fonts for Dynamic Type](https://useyourloaf.com/blog/auto-adjusting-fonts-for-dynamic-type/) from Use Your Loaf.

-   Chris Sessions

    Software Engineer

    [More from Chris](/team/chris-sessions/)

    Chris Sessions

### Tags

[Accessibility](/insights/all/?topic=accessibility) [Digital Engineering](/insights/all/?topic=digital-engineering) [Mobile Apps](/insights/all/?topic=mobile-apps)

### Share

-   Copied

## View these next.

[See all](/insights/all/?type=writing)

-   [

    Article

    How To Sabotage Your Project Using Inconsistency

    Collin Flynn

    ](/writing/how-to-sabotage-your-project-using-inconsistency/)
-   [

    Article

    Unit Testing race conditions by creating chaos (Swift)

    Sean Berry

    ](/writing/unit-testing-race-conditions-by-creating-chaos-swift/)
-   [

    Article

    UIApplicationDelegate call sequence reference

    Sean Berry

    ](/writing/uiapplicationdelegate-call-sequence-reference/)
