Reputation: 6005
If I have my own group of UIFont
s with different sizes and weights, for example:
let customFont03 = UIFont.systemFont(ofSize: 40, weight: .thin)
How can I support Dynamic Type
while still preserving my custom size and weight as a default standard and scaling that depending on how the user selects accessibility sizes?
I'm not sure that preferredFont(forTextStyle:)
is what I want because it only accepts a UIFont.TextStyle
and I don't want to lock customFont03
in as a .body
or .headline
etc...
Upvotes: 10
Views: 4292
Reputation: 6983
In Swift 5.
I can't believe Apple didn't provide a cleaner way to get a dynamic font with a specific weight. Here's my comprehensive solution, hope this helps!
extension UIFont {
static func preferredFont(for style: TextStyle, weight: Weight, italic: Bool = false) -> UIFont {
// Get the style's default pointSize
let traits = UITraitCollection(preferredContentSizeCategory: .large)
let desc = UIFontDescriptor.preferredFontDescriptor(withTextStyle: style, compatibleWith: traits)
// Get the font at the default size and preferred weight
var font = UIFont.systemFont(ofSize: desc.pointSize, weight: weight)
if italic == true {
font = font.with([.traitItalic])
}
// Setup the font to be auto-scalable
let metrics = UIFontMetrics(forTextStyle: style)
return metrics.scaledFont(for: font)
}
private func with(_ traits: UIFontDescriptor.SymbolicTraits...) -> UIFont {
guard let descriptor = fontDescriptor.withSymbolicTraits(UIFontDescriptor.SymbolicTraits(traits).union(fontDescriptor.symbolicTraits)) else {
return self
}
return UIFont(descriptor: descriptor, size: 0)
}
}
You can use it like this:
UIFont.preferredFont(for: .largeTitle, weight: .regular)
UIFont.preferredFont(for: .headline, weight: .semibold, italic: true)
Upvotes: 19
Reputation: 173
UIFontMetrics
is the class designed to solve this problem. In particular -[UIFontMetrics scaledFontForFont:]
will do what you ask, but be sure to check out the other members of that class, which can do things like cap the font increase at some maximum (at the very largest content size categories a size 40 font would be scaled to a very large size indeed).
https://developer.apple.com/documentation/uikit/uifontmetrics/2877385-scaledfontforfont
Upvotes: 0