Proper Font Scaling Matters to Your Users

How to apply font scaling to your iOS app without breaking your layout

Kevin R
Better Programming

--

Photo by Clément Falize on Unsplash

Most developers that will read this have pretty good eyesight. But chances are, not all of your users are as lucky.

Nearsightedness, (partial) color blindness or other impairments may affect how a person perceives your app, or more importantly: if a person is able to navigate your app at all.

Designers may prefer a minimalistic design, which includes small, pretty fonts and a light color palette. Often the font sizes and space allocated for an element are well-thought-out choices to ensure the interface looks beautiful and balanced.

However, the readability of your app is likely to be affected by those design choices: what looks pretty may not work the best. Then again, does that really matter? Would you rather have a beautiful app or one that’s usable?

On the other hand, I’m one of those people that prefer setting the text size to the smallest, and I expect apps that I use to adhere to that choice.

Apps that do not adhere to my preference feel out of place, using them might just become a nuisance rather than a joy.

In practice, I would suggest the following: Design your app to look great for the default content size scale, then adhere to user preferences and scale your UI accordingly.

Fortunately, Apple has made it easy for you to help out your users. There’s a number of APIs available to help you help others. For starters, some areas that you should consider keeping in mind are:

  • Text: Font sizes and text boldness should adhere to user preferences.
  • Colors: Ensure there is enough contrast between colors and preferably increase contrast if the user has this setting enabled.
  • Accessibility properties: Components should have properties such as accessibilityLabel and accessibilityValue set. This helps VoiceOver read out useful information about elements.

We will be focusing on text scaling and layout, as it is a very good starting point and likely easy to implement in your app.

To get an idea of how Apple approaches this, take a look at any of the default apps provided in iOS such as the clock app:

Changing the device’s content size influences what the interface looks like. You can check the bottom of the article for tips on how to change the text size on your device.

There are a few interesting things to point out.

Buttons do not scale

This goes for the buttons in the tab bar and navigation bar. This also is the default behavior for UIButton instances you will create in your own app.

However, they will become bold when “Bold Text” is enabled in Settings.
This behavior may seem somewhat counterintuitive and can be changed by changing the titleLabel properties.

The time label changes places

When the font size gets too large, the app changes the layout to ensure labels don’t get cut off and become useless.

Not all labels scale equally

Notice the city name doesn’t change as much as the timezone label above it.

Furthermore, the time label doesn’t change its size at all. The reasoning behind it is simple: those labels are already quite big, scaling them up too much would actually decrease the legibility.

Applying This to Code

There is a set of APIs to help you achieve the same behavior in your own app. Let’s take the Clock app as an example and try to mimic it. The setup of the cell can be as simple as this in terms of layout:

Three UILabels and two UIStackViews to set up the cell. Note the labels on the left have a text style set.

Scaling fonts automatically

UIFont has a nice API to specify what kind of font you need. Using TextStyle, you can ask the system for a font that understands the current interface traits:

UIFont.preferredFont(forTextStyle: .caption1)

This very convenient, the given font neatly fits the device it’s being used on and scales automatically if needed. The next step is telling the component to adhere to size change:

You can also achieve this in a storyboard:

Choosing a text style from a storyboard, be sure to also select “Automatically Adjust Font”.

Now the real fun begins. Once the fonts scale properly, you will likely find out not all text will fit in the space you’ve allocated for it. A good start is to make more labels multiline. But what if you want to change the layout?

Changing the layout when the font size changes

Many elements that make up the device configuration are defined as traits. These traits are placed in a UITraitCollection. Both subclasses of UIView and UIViewController have a property to check its trait information.

There’s a lot of information to be found in here, but in our case, we want to check the text size category:

// Get this property from any UIView or UIViewController:
traitCollection.preferredContentSizeCategory

Let’s assume you placed the labels in a UIStackView, this will allow you to quickly change the axis based on the content size category:

Now, you’ll also want the interface to update if the font size is changed while the app is running. Both UIView and UIViewController also have a function you can UIoverride to listen for changes:

And that’s it! You can test it directly from the debugger using the “Environment Overrides” button:

Bonus Tips

Switch between text sizes on your device

Switching between text sizes can also be done directly from the control center on your device. Under Settings, go to Control Centre, then Customize Controls, and include Text Style.

Extra-large text sizes

By default, extra-large text sizes are not enabled. To test them, you can enable these under Settings, Accessibility, Display & Text Size, Larger Text.

How to enable larger text sizes for accessibility

--

--

iOS Developer, Swift enthousiast. Working for Team Rockstars IT in the Netherlands