I'm playing around with SwiftUI, and want to use a custom UI font for my project. However, I don't want to lose the dynamic type resizing that comes with the built-in font classes (e.g. Large Title).
Apple does provide a custom font modifier for Text
:
Text("Hello, world!")
.font(.custom("Papyrus", size: 17))
However, this fixes the size to 17pt. When you run this on a device or in the Simulator and open the Accessibility Inspector to adjust the OS-level font size, the Text
element does not update.
The size:
parameter is not optional, so you must pass in something. And unfortunately, you can't get the size
of an existing font (even a custom one), because Font
does not have a size
parameter.
It seems to be a common pattern in the rest of SwiftUI that parameters can either be optional, or you can pass in nil
to explicitly disable certain behavior. I would expect the size:
parameter on .custom()
to be optional, and internally either use the size from a previous Font
modifier, or to use the default size set by Text
.
Alternately, the static methods that define system styles (e.g. .largeTitle
) could accept an argument that provides a custom font name: .largeTitle("Papyrus")
Does anyone have a workaround?
Best Answer
The way I would do it, is by creating a custom modifier that can be bound to the changes of the environment's size category:
Whenever you need to use Papyrus, you would use it like this:
or like this:
Your text will now dynamically change without further work. This is the same code, reacting to different text size preference:
And your Papyrus() implementation will look something like this. You'll need to figure out the right values for each category, this is just an example:
UPDATE
I modified the implementation to accept a text style as parameter.