Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Default UIFont size and weight but also support preferredFontForTextStyle

If I have my own group of UIFonts 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...

like image 851
Turnipdabeets Avatar asked Nov 17 '18 23:11

Turnipdabeets


1 Answers

Dynamic system font, specifying Style, Weight, and Italics

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)
like image 189
beebcon Avatar answered Oct 13 '22 17:10

beebcon