I'm in the process of upgrading my app from UIKit to SwiftUI and I've run into the issue of how to create a SwiftUI Text
view which reacts to dynamic (accessible) font size and uses a variable font file.
In UIKit, we can create a UILabel view doing this using UIFontDescriptor:
public enum FontVariations: Int {
case weight = 2003265652
}
let uiFontDescriptor = UIFontDescriptor(fontAttributes: [.name: "Inter", kCTFontVariationAttribute as UIFontDescriptor.AttributeName: [FontVariations.weight.rawValue: 400])
let customFont = UIFont(descriptor: uiFontDescriptor, size: 18)
let scaledFont = UIFontMetrics(forTextStyle: .body).scaledFont(for: customFont)
let label = UILabel()
label.font = scaledFont
label.adjustsFontForContentSizeCategory = true
label.text = "Hello, World!"
If we add this UILabel to a screen, we should see the variable font with weight 400 (regular), font size 18, and it should scale depending on the user's dynamic font size.
Since we're using variable fonts, we can feed in this UIFont using swift's Font initializer and try applying it to a Text view
Text("Hello, World!")
.font(Font(scaledFont))
The issue is that this doesn't respond to the dynamic text size. Apple recommends doing
Text("Hello, World!")
.font(.custom("Inter", size: 18, relativeTo: .body))
but this doesn't allow me to use a variable fonts with modified font axis'. I'm hoping to either make the Font(UIFont) initializer work with dynamic sizing or find another way to use variable fonts in SwiftUI that let me use the relativeTo initializer.
You can use ScaledMetric
to make anything relative to a dynamic type:
@ScaledMetric(relativeTo: .body) var dynamicSize = 18
So you can use your custom UIFont
with a dynamic size:
Text("Hello World")
.font(Font(customFont.withSize(dynamicSize)))