---
title: "Practical Dynamic Type, Part 3: Attributed Text"
source: "/writing/practical-dynamic-type-part-3-attributed-text/"
---

Article

# Practical Dynamic Type, Part 3: Attributed Text

Keehun Nam

February 19, 2019

Ensuring that applications remain accessible for all is one of our highest priorities at [Livefront](https://livefront.com) , and we believe that a key component in achieving that goal is to flawlessly support Dynamic Type in all of our applications. [Part 1](/writing/practical-dynamic-type) of our _Practical Dynamic Type_ series focused on supporting iOS 10 and [Part 2](/writing/practical-dynamic-type-part-2-testing) focused on unit testing. This third installment will focus on Attributed Strings.

_You can access the complete demo app for this article,_ [_here_](https://github.com/keehun/Dynamic-Type-Part-3-Demo-Project) _._

You may be asking: "Isn't there already `adjustsFontForContentSizeCategory`?" You're right! Setting aside for a moment the fact that it is not unit testable (as discussed in [Part 2](/writing/practical-dynamic-type-part-2-testing) ), let's see what happens when we assign an Attributed String to an `UILabel` with `adjustsFontForContentSizeCategory = true`.

**On iOS 11 and above, everything works as expected**

A gif demonstrating that Attributed Strings resize properly on iOS 12.

UILabel on iOS 11 correctly responds to `adjustsFontForContentSizeCategory`.

**But, on iOS 10, an** `**AttributedString**` **in an** `**UILabel**` **does not respond to** `**adjustsFontForContentSizeCategory**`**.**

A gif demonstrating that Attributed Strings does not resize properly on iOS 10.

`**UILabel**` **on iOS 10 does not respond to** `**adjustsFontForContentSizeCategory**` **due to the lack of** `**UIFontMetrics**` **on iOS 10.**

## Let's fix this

It's clear from attempting to use `adjustsFontForContentSizeCategory` on iOS 10 that we will have to manually handle updating the font size, just as we've done in [Part 1](/writing/practical-dynamic-type) and [Part 2](/writing/practical-dynamic-type-part-2-testing) .

First, let's define a `UIView` that hosts a `UILabel` displaying multiple attributed strings:

​(Note that you will need to pull the `FontMetrics` class from [Part 2](/writing/practical-dynamic-type-part-2-testing) .)

Second, let's hook into `FontMetric`'s notification `FontMetricsContentSizeCategoryDidChange`:

## What's next?

Whereas we've been able to set the font size property on the entire `UILabel` inside the `uiContentSizeCategoryChanged()` before, now we will have to set the type size on each individual formatted segment within the `AttributedString` as each formatting segment may have different type size. Therefore, in response to `ContentSizeCategoryDidChange`, we will have to enumerate through each formatting segment of the overall `AttributedString` and update each formatted segments' type sizes.

Let's first enumerate over the `AttributeString` to access each of the four sub-attributed strings we created above:

In order to calculate the new type sizes, we will need to have separate `FontSetter` closures that the enumeration block in `uiContentSizeCategoryChanged()` can use on each attributed substring (see lines 11, 20, 31, and 40 below). This allows the individual attributed substring to get its type size regenerated with its own `FontSetter`.

And now, all we have to do is get a new `UIFont` with updated sizes by re-executing the `FontSetter` closure for each substring and then assigning those new fonts to the preexisting string:

A gif demonstrating that Attributed Strings now resize properly on iOS 10.

UILabel on iOS 10 now responds to Dynamic Type.

## Unit Testing

Using this technique, it is possible to unit test the Dynamic Type `pointSize` as well!

Which, as expected, passes!

Now, you can support Dynamic Type with `AttributedString` on pre-iOS 11 devices, and unit test it, too! 🍰

You can access the complete demo app for this article [here](https://github.com/keehun/Dynamic-Type-Part-3-Demo-Project) . (Please note that Neutraface Slab Text font shown throughout the article is not included, and it has been replaced with Courier.)

_Keehun finds ways to unit test everything at_ [_Livefront_](https://livefront.com) _._

-   Keehun Nam

    Software Engineer

    Keehun Nam

### 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/)
