Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Add custom weight to iOS Font descriptor in Swift

This seems like it should be rudimentarily easy, but for whatever reason it's not working. I've read similar posts on SO and it seems like there might be an issue with the Font Traits dictionary? Is this an issue or am I just completely missing something? This is my first time messing around with fonts like this so I think it might be the latter.

I don't want to use the constants or supply a font with it's "-bold" variant. I would like to have fine grain control over the font weight.

let traits = [UIFontWeightTrait : 1.0]
imgFontDescriptor = UIFontDescriptor(fontAttributes: [UIFontDescriptorNameAttribute: "Helvetica"])
imgFontDescriptor = imgFontDescriptor.fontDescriptorByAddingAttributes([UIFontDescriptorTraitsAttribute:traits])
imgTextFont = UIFont(descriptor: imgFontDescriptor!, size: 24.0)

Research:

  • Font Descriptor returns nil in iOS 8
  • https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIFontDescriptor_Class/#//apple_ref/doc/constant_group/Font_Traits_Dictionary_Keys

According to the iOS docs using a number value should work (I'm running iOS 9.2):

UIFontWeightTrait

The normalized weight value as an NSNumber object. The valid value range is from -1.0 to 1.0. The value of 0.0 corresponds to the regular or medium font weight. You can also use a font weight constant to specify a particular weight; for a list of constants you can use, see Font Weights. Available in iOS 7.0 and later.

like image 504
Tim Sanders Avatar asked Jan 04 '16 03:01

Tim Sanders


People also ask

How do I change the font weight of a custom font in Swift?

The normalized weight value as an NSNumber object. The valid value range is from -1.0 to 1.0. The value of 0.0 corresponds to the regular or medium font weight. You can also use a font weight constant to specify a particular weight; for a list of constants you can use, see Font Weights.

How do I add custom fonts to my iPhone?

You can download fonts from the App Store app , then use them in documents you create on iPhone. After you download an app containing fonts from the App Store, open the app to install the fonts. To manage installed fonts, go to Settings > General, then tap Fonts.


1 Answers

If you use existing fontDescriptor (for example from existing font), it may not working, because of explicit '.name' attribute in fontDescriptor.fontAttributes.

Solution, that works for me (Swift 4):

extension UIFont {
    var bold: UIFont { return withWeight(.bold) }
    var semibold: UIFont { return withWeight(.semibold) }

    private func withWeight(_ weight: UIFont.Weight) -> UIFont {
        var attributes = fontDescriptor.fontAttributes
        var traits = (attributes[.traits] as? [UIFontDescriptor.TraitKey: Any]) ?? [:]

        traits[.weight] = weight

        attributes[.name] = nil
        attributes[.traits] = traits
        attributes[.family] = familyName

        let descriptor = UIFontDescriptor(fontAttributes: attributes)

        return UIFont(descriptor: descriptor, size: pointSize)
    }
}

Usage:

let baseFont = UIFont(name: "American Typewriter", size: 20)!
let boldFont = baseFont.bold
let semibold = baseFont.semibold
like image 52
Andrey Avatar answered Oct 09 '22 03:10

Andrey