Search code examples
objective-ccocoa-touchios7nsattributedstringtypography

Use medieval (lowercase, non-lining) numbers


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


Solution

  • 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;