Supporting Bold Text with Custom Fonts in SwiftUI

joshpensky

Josh Pensky

Posted on July 19, 2022

Supporting Bold Text with Custom Fonts in SwiftUI

When building for accessibility, there are a lot of preferences to keep in mind! For some people, reading bold text increases their comprehension. Enter the Bold Text preference: an iOS setting that increases the weight of all text to ensure this better legibility.

Users can enable the bold text preference by visiting Settings, Accessibility, Display & Text Size, and toggling the Bold Text switch.

When a user enables the Bold Text preference, everything in the user interface becomes bolder for better legibility. Regular text turns semibold, semibold text turns bold, and bold text turns black (yes, even bold text is bolded!). This also applies to variants like italics.

As UI engineers, we need to account for this preference when we're building interfaces. If you're using the default system font, it's your lucky day — this is already taken care of for you by Apple! But if you're using a custom typeface, well it's also your lucky day because you found this article!

Here's the code we're aiming for:

Text("Lorem ipsum dolor sit amet.")
    .accessibilityFont(.body)
Enter fullscreen mode Exit fullscreen mode

Before you get started, it's a good idea to alert the designers on your team to the Bold Text preference as they will need to purchase the additional weights as needed.

First, let's set up a model that will hold our accessible font data. Here, we'll define both a regular and bold variant of our font that we can switch between.

struct AccessibleFont {
    var regular: Font
    var bold: Font

    init(_ regular: Font, bold: Font) {
        self.regular = regular
        self.bold = bold
    }

    func value(_ legibilityWeight: LegibilityWeight?) -> Font {
        switch legibilityWeight {
        case .bold:
            return bold
        default:
            return regular
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

Now that we have a model to define our fonts, let's create an example for our body font. When the Bold Text preference is enabled, we should use our custom bold font; otherwise, we should use the regular font.

extension AccessibleFont {
    static var body: AccessibleFont {
        AccessibleFont(
            regular: Font.custom("CustomFont-Regular", 17.0),
            bold: Font.custom("CustomFont-Bold", 17.0)
        )
    }
}
Enter fullscreen mode Exit fullscreen mode

Next, we'll define a view modifier (like .font(_:)) that we can use on our views. Using the legibilityWeight environment value, we can determine what the true font should be based on the user's preference.

struct AccessibilityFontViewModifier: ViewModifier {
    @Environment(\.legibilityWeight) private var legibilityWeight

    var font: AccessibleFont

    func body(content: Content) -> some View {
        content.font(font.value(legibilityWeight))
    }
}
Enter fullscreen mode Exit fullscreen mode

For easy reference, we'll also include a handy .accessibilityFont(_:) function on View.

extension View {
    func accessibilityFont(_ font: AccessibleFont) -> some View {        
        return self.modifier(AccessibilityFontViewModifier(font: font))
    }
}
Enter fullscreen mode Exit fullscreen mode

If we put this all together, we get our original example! Now when the Bold Text preference is enabled, SwiftUI will render our text bold in realtime.

Text("Lorem ipsum dolor sit amet.")
    .accessibilityFont(.body)
Enter fullscreen mode Exit fullscreen mode

Bold Text is just one preference that users can enable to create an accessible experience. No matter what the user toggles, be it Bold Text or Invert Colors, we as engineers should work to support it!

💖 💪 🙅 🚩
joshpensky
Josh Pensky

Posted on July 19, 2022

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related