iOS 9 Proportional Numbers

The WWDC 2015 session 804 Introducing the New System Fonts covers the new San Francisco font families that Apple is introducing with OS X 10.11, iOS 9 and watchOS. If you did not make it to the end of the session you may have missed another important change. The default for how numbers are displayed is changing from monospaced to proportional:

Proportional numbers by default, opt into monospaced

To see where this might not be what you want consider the following example. Two static text labels containing numbers would by default on iOS 8 be monospaced and align vertically:

iOS 8 monospaced numbers

Once this app is rebuilt with the iOS 9 SDK and run on an iOS 9 device the numbers are displayed using a proportional font which messes with the alignment:

iOS 9 proportional numbers

Changing Font Features in Code

Monospaced numbers are a font feature that can, in theory, be enabled in the Typography panel (accessed from the font panel, look for the Typography option under the settings menu). I say in theory as I am still using OS X 10.10 which does not have the new font panel.

Luckily the WWDC session also provides some code snippets for enabling features. The labels in my example are using the dynamic type text styles introduced with iOS 7. To modify the text style to enable monospaced numbers we first need to get a font descriptor:

let bodyFontDescriptor = UIFontDescriptor.preferredFontDescriptorWithTextStyle(UIFontTextStyleBody)

We then create a new font descriptor by adding an attribute to the body font descriptor that specifies the monospaced number feature:

let bodyMonospacedNumbersFontDescriptor = bodyFontDescriptor.fontDescriptorByAddingAttributes(
    [
      UIFontDescriptorFeatureSettingsAttribute: [
        [
          UIFontFeatureTypeIdentifierKey: kNumberSpacingType,
          UIFontFeatureSelectorIdentifierKey: kMonospacedNumbersSelector
        ]
      ]
    ])

Finally we create the font from the font descriptor and apply it to the label:

let bodyMonospacedNumbersFont = UIFont(descriptor: bodyMonospacedNumbersFontDescriptor, size: 0.0)
textLabel.font = bodyMonospacedNumbersFont

Notes:

The final appearance on iOS 9 for a body text style with monospaced numbers is as follows:

iOS 9 monospaced numbers

Alternate Styles

As an added bonus there are also a couple of stylistic alternatives to the way the 4, 6 and 9 are displayed. You can enable these style alternatives in much the same way we enabled monospaced numbers by adding an attribute to a base font descriptor.

Alternate Style One (6 and 9)

This first alternate style changes both the 6 and 9:

let bodyAltStyle1Descriptor = bodyFontDescriptor.fontDescriptorByAddingAttributes(
    [
      UIFontDescriptorFeatureSettingsAttribute: [
        [
          UIFontFeatureTypeIdentifierKey: kStylisticAlternativesType,
          UIFontFeatureSelectorIdentifierKey: kStylisticAltOneOnSelector
        ]
      ]
    ])

let altStyle1BodyFont = UIFont(descriptor: bodyAltStyle1Descriptor, size: 0.0)
textLabel.font = altStyle1BodyFont

The changed visual appearance is shown below with the alternate 6 and 9 digits highlighted:

alternate 6,9

Alternate Style Two (4)

This second alternate style changes the 4:

let bodyAltStyle2Descriptor = bodyFontDescriptor.fontDescriptorByAddingAttributes(
    [
      UIFontDescriptorFeatureSettingsAttribute: [
        [
          UIFontFeatureTypeIdentifierKey: kStylisticAlternativesType,
          UIFontFeatureSelectorIdentifierKey: kStylisticAltTwoOnSelector
        ]
      ]
    ])

let altStyle2BodyFont = UIFont(descriptor: bodyAltStyle2Descriptor, size: 0.0)
txtLabel.font = altStyle2BodyFont

The changed visual appearance of the digit 4 is highlighted below:

alternate 4

Never miss a post!

iOS Size Classes Cheat Sheet

Subscribe and get my free iOS Size Classes Cheat Sheet

Unsubscribe at any time.
No time to watch WWDC videos?

Sign up to get my iOS posts direct to your inbox and I will send you a free PDF of my iOS Size Classes Cheat Sheet.

Unsubscribe at any time.
Archives Categories
comments powered by Disqus