Been digging into details about UIFont and Dynamic Type recently. Come swim with me in a sea of tiny details for a moment. 🧵
So generally speaking there's two canonical ways to get fonts that support Dynamic Type: preferred fonts and system fonts + UIFontMetrics.

The preferred font APIs are great if you just need default point sizes, but if you need different point sizes or weights, things get...weird
First, it's important to know that preferredFont APIs adjust font leadings, while systemFont APIs do not.

In other words, systemFont APIs result in denser lines of text than equivalent preferredFont APIs which have been tuned.
The preferred fonts APIs go out of their way to dial in this leading behavior, with different leading values being assigned to the font at every size category:
It's not just line spacing that's different, though. UITableView section headers will compensate for non-zero leading by reducing the amount of padding in section headers to afford *more* information density on screen.
So preferredFont is the way to go...but what happens when you need a font with a different point size or weight?

Create the system font you need and pass it through UIFontMetrics' scaledFontForFont:, right?

Not quite.
Remember that first detail about line spacing? Turns out even if you pass a systemFont through UIFontMetrics, that leading detail is never applied. 😱
Thankfully it is possible to both create a font with a custom point size *and* maintain Apple's dialed in leading values, but prior to iOS 14 it was a bit of a mixed bag of behavior.
The dance:

1. Use UIFontDescriptor.preferredFontDescriptorWithTextStyle to make a font descriptor. Add weight/italic attributes as needed.
2. Pass it to UIFont.fontWithDescriptor:size:
3. Associate a text style with the font via UIFontMetrics.

This only really works on iOS 14
For iOS 12 and 13 there's a scattering of iOS bugs and unexpected behavior that result in a windy road toward a swiss cheese of dialed in fonts, but it kind of works for common cases. You can see the different considerations in gist.github.com/jverkoey/e5965….
With the iOS 14 solution, your custom preferred fonts' leading will now dynamically adjust based on the initial point size 💯

Here's a screenshot of some of the leading values that will be generated:
Note that the trade-off to this approach is that the low and top-end size category point sizes are different than the equivalent direct preferredFont API, even for the same base point size, so you will want to consistently use the dance outlined above if you use it at all.
Be sure to check out the HIG for a deeper appreciation of how and when leading can be further tweaked: developer.apple.com/design/human-i….
Summarizing:

- Don't just use system font APIs. Prefer preferred font APIs.
- For custom sizes/weights, use preferred font descriptors to make Dynamic Type-compatible system fonts that also adjust leading.
- Consider using traitLooseLeading and traitTightLeading if needed.

fin.
Also: I'd love to make clarifications + improvements to this if others have encountered similar things. Please let me know if anything's totally off the mark!

• • •

Missing some Tweet in this thread? You can try to force a refresh
 

Keep Current with Jeff Verkoeyen

Jeff Verkoeyen Profile picture

Stay in touch and get notified when new unrolls are available from this author!

Read all threads

This Thread may be Removed Anytime!

PDF

Twitter may remove this content at anytime! Save it as PDF for later use!

Try unrolling a thread yourself!

how to unroll video
  1. Follow @ThreadReaderApp to mention us!

  2. From a Twitter thread mention us with a keyword "unroll"
@threadreaderapp unroll

Practice here first or read more on our help page!

Did Thread Reader help you today?

Support us! We are indie developers!


This site is made by just two indie developers on a laptop doing marketing, support and development! Read more about the story.

Become a Premium Member ($3/month or $30/year) and get exclusive features!

Become Premium

Too expensive? Make a small donation by buying us coffee ($5) or help with server cost ($10)

Donate via Paypal Become our Patreon

Thank you for your support!

Follow Us on Twitter!