8

I have a request from a customer to use a certain font in a iOS 7 project because it has medieval numbers.

Is there any way to activate those numbers for a NSAttributedString? As default lining numbers are used, that are included in the font as-well.


Here is an example. Both lines have the same font with no variant (Regular), once with medieval numbers activated, the second wit the default lining numbers.

enter image description here

vikingosegundo
  • 52,040
  • 14
  • 137
  • 178

2 Answers2

11

These are called lowercase numbers and can be turned on using UIFontDescriptor.

First, you need to import CoreText for some constants:

#import <CoreText/SFNTLayoutTypes.h>
or
@import CoreText.SFNTLayoutTypes;

Then create font using font descriptor. Here I use Georgia family:

NSDictionary *lowercaseNumbers = @{
                                   UIFontFeatureTypeIdentifierKey: @(kNumberCaseType),
                                   UIFontFeatureSelectorIdentifierKey: @(kLowerCaseNumbersSelector),
                                   };
UIFontDescriptor *descriptor = [[UIFontDescriptor alloc] initWithFontAttributes:
                                @{
                                  UIFontDescriptorFamilyAttribute: @"Georgia",
                                  UIFontDescriptorFeatureSettingsAttribute:@[ lowercaseNumbers ],
                                  }];
UIFont *font = [UIFont fontWithDescriptor:descriptor size:15];

Result:
enter image description here

Edit: As @Random832 pointed out, Georgia has only lowercase numbers, so the result is irrelevant. However, @vikingosegundo confirmed this code works on supported fonts. Thanks.

enter image description here

The top line was generated with

UIFont *font = [UIFont fontWithName:@"DIN Next LT Pro" size:12];
if (font)
    label.font = font;

the second line with

NSDictionary *lowercaseNumbers = @{  UIFontFeatureTypeIdentifierKey:@(kNumberCaseType), UIFontFeatureSelectorIdentifierKey: @(kLowerCaseNumbersSelector)};
UIFontDescriptor *descriptor = [[UIFontDescriptor alloc] initWithFontAttributes:
                                @{UIFontDescriptorFamilyAttribute: @"DIN Next LT Pro",UIFontDescriptorFeatureSettingsAttribute:@[ lowercaseNumbers ]}];
UIFont *font = [UIFont fontWithDescriptor:descriptor size:12];
if (font)
    label.font = font;
vikingosegundo
  • 52,040
  • 14
  • 137
  • 178
Tricertops
  • 8,492
  • 1
  • 39
  • 41
  • No problem. It's worth looking into _SFNTLayoutTypes.h_, you may find some more interesting features, like proportional numbers or alternative punctuation. – Tricertops Feb 27 '14 at 13:56
  • 2
    I guess the biggest problem is the wording. Typography has so many Vocabulary I don't know. even in my own mother language. – vikingosegundo Feb 27 '14 at 13:58
  • @vikingosegundo In that case, you have to try all of them to see what they do ;) – Tricertops Feb 27 '14 at 19:09
  • Georgia has lowercase numbers by default and I'm not sure if it has uppercase numbers, maybe an example with a different font for the example? – Random832 Feb 27 '14 at 19:13
  • @Random832: I use DIN Next LT Regular. It is not freely available. But it has both - non-lining and lining numerals. And iMartins code is working with it. – vikingosegundo Feb 28 '14 at 01:54
  • @Random832 Ouch, you are right :D I will try to finding one that has both. – Tricertops Feb 28 '14 at 14:56
  • I found both _Didot_ and _Marion_ to have lowercase numbers on OS X, but none of them are present on iOS. Please, @vikingosegundo, could you edit my answer by providing screenshots of your font? :) – Tricertops Feb 28 '14 at 15:06
  • @iMartin: with pleasure – vikingosegundo Feb 28 '14 at 15:41
2

Another question has a pointer in the right direction, though the question mentions tabular figures [vs proportional] rather than text vs lining.

It looks like you can use CTFontDescriptorCreateCopyWithFeature with kNumberCaseType set to kLowerCaseNumbersSelector to display the digits this way.

Here's another related question, and here's the blog post provided in the answer.

Community
  • 1
  • 1
Random832
  • 37,415
  • 3
  • 44
  • 63