In Apple's Apple Watch Design Resources, there is a document called Alternate Font Weights and Italicizations. In it, it shows examples of what the default font looks like with different attributes such as Italic, Emphasized, and Short applied to it.
Assume I want to use a font that looks exactly like the "Short" example.
Is there any way to choose this font and style via the storyboard for a label?
In code, how would I set a label to use this font and style?
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.