How to use alternate font weights (e.g. “short”) in a WKInterfaceLabel?

拥有回忆 提交于 2019-12-06 04:34:48
Senseful

In an iOS project, I tried modifying the body font (UIFontTextStyleBody) to include UIFontDescriptorTraitTightLeading. When I read the fontAttributes properties, it reports the NSFontNameAttribute as .AppleSystemUIShortBody (the original value is .AppleSystemUIBody).

From this, I was able to figure out Apple's terms:

+------------+-----------------------------------+------------------------------+---------------------------------+
|    Term    |  UIFontDescriptorSymbolicTraits   |     NSFontNameAttribute      |    NSCTFontUIUsageAttribute     |
+------------+-----------------------------------+------------------------------+---------------------------------+
|            | (none)                            | .AppleSystemUIBody           | UICTFontTextStyleBody           |
| Italic     | UIFontDescriptorTraitItalic       | .AppleSystemUIItalicBody     | UICTFontTextStyleItalicBody     |
| Emphasized | UIFontDescriptorTraitBold         | .AppleSystemUIEmphasizedBody | UICTFontTextStyleEmphasizedBody |
| Short      | UIFontDescriptorTraitTightLeading | .AppleSystemUIShortBody      | UICTFontTextStyleShortBody      |
| Tall?      | UIFontDescriptorTraitLooseLeading | .AppleSystemUISpliceTallBody | UICTFontTextStyleTallBody       |
+------------+-----------------------------------+------------------------------+---------------------------------+

If you attempt to do the same thing with UIFontDescriptorTraitExpanded, UIFontDescriptorTraitCondensed, UIFontDescriptorTraitVertical, UIFontDescriptorTraitUIOptimized, and then read the fontAttributes, it returns the same value as the Body style. If you try the same thing with UIFontDescriptorTraitMonoSpace, it returns a nil dictionary.

Therefore, in an Apple Watch project, you should be able to use the Body Short Emphasized font like so:

/*1*/ UIFontDescriptor *fontDescriptor = [UIFontDescriptor preferredFontDescriptorWithTextStyle:UIFontTextStyleBody];
/*2*/ fontDescriptor = [fontDescriptor fontDescriptorWithSymbolicTraits:UIFontDescriptorTraitTightLeading | UIFontDescriptorTraitBold];
/*3*/ UIFont *font = [UIFont fontWithDescriptor:fontDescriptor size:0];
/*4*/ [label setAttributedText:[[NSAttributedString alloc] initWithString:text attributes:@{NSFontAttributeName: font}]];

I say "should" because there are two bugs in play here:

  • On line 2, UIFontDescriptorTraitTightLeading is being specified, yet this trait is ignored on both watch simulators. Bold and italic work just fine.
  • On line 3, since size is set to 0, it gets its value from the UIFontDescriptorSizeAttribute in fontDescriptor [1]. The problem is that on a 38mm device, there is a bug with both +[UIFontDescriptor preferredFontDescriptorWithTextStyle:] and -[UIFont preferredFontForTextStyle:] (used on line 1). When the user doesn't customize the font size, both methods return 16, when clearly 15 should be chosen on the 38mm device. (You can verify this by placing a label on a storyboard, assigning it the Body size, and visually comparing it to a label that sets its size to 15 manually.)

Note: I am running Xcode 6.2.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!