Как получить моноширинные номера в UILabel на iOS 9

на WWDC 2015 была сессия о новом системном шрифте "Сан-Франциско" в iOS 9. Он использует пропорциональный рендеринг чисел вместо одноместных чисел по умолчанию при связывании с iOS 9 SDK. На NSFont есть удобный инициализатор под названием NSFont.monospacedDigitsSystemFontOfSize(mySize weight:) который можно использовать для явного включения отображения одноместных чисел.

однако я не мог найти UIKit эквивалент для этого на UIFont.

7 ответов


удобная


теперь это доступно в UIFont начиная с iOS 9:

+ (UIFont *)monospacedDigitSystemFontOfSize:(CGFloat)fontSize weight:(CGFloat)weight NS_AVAILABLE_IOS(9_0);

например:

[UIFont monospacedDigitSystemFontOfSize:42.0 weight:UIFontWeightMedium];

или в Swift:

UIFont.monospacedDigitSystemFont(ofSize: 42.0, weight: UIFontWeightMedium)

принятое решение отлично работает, но сбой с оптимизацией компилятора установлен на Fast(по умолчанию для сборок выпуска). Переписал код вот так и теперь его нет:

extension UIFont
{
    var monospacedDigitFont: UIFont
    {
        return UIFont(descriptor: fontDescriptor().fontDescriptorByAddingAttributes([UIFontDescriptorFeatureSettingsAttribute: [[UIFontFeatureTypeIdentifierKey: kNumberSpacingType, UIFontFeatureSelectorIdentifierKey: kMonospacedNumbersSelector]]]), size: 0)
    }
}

в Swift 4 было довольно много переименований, поэтому атрибуты теперь выглядят так:

    let fontDescriptorAttributes = [
        UIFontDescriptor.AttributeName.featureSettings: [
            [
                UIFontDescriptor.FeatureKey.featureIdentifier: kNumberSpacingType,
                UIFontDescriptor.FeatureKey.typeIdentifier: kMonospacedNumbersSelector
            ]
        ]
    ]

Примечание: метод в принятом в настоящее время ответе начал сбой для меня в Xcode 7.3 (Swift 2.2), только в сборках выпуска. Устранение посредника monospacedDigitFontDescriptor переменная расширения устраняет проблему.

extension UIFont {
    var monospacedDigitFont: UIFont {
        let fontDescriptorFeatureSettings = [[UIFontFeatureTypeIdentifierKey: kNumberSpacingType, UIFontFeatureSelectorIdentifierKey: kMonospacedNumbersSelector]]
        let fontDescriptorAttributes = [UIFontDescriptorFeatureSettingsAttribute: fontDescriptorFeatureSettings]
        let oldFontDescriptor = fontDescriptor()
        let newFontDescriptor = oldFontDescriptor.fontDescriptorByAddingAttributes(fontDescriptorAttributes)

        return UIFont(descriptor: newFontDescriptor, size: 0)
    }
}

немного улучшенная версия кода @Rudolf Adamkovic, который проверяет версию iOS:

var monospacedDigitFont: UIFont {

    if #available(iOS 9, *) {
        let oldFontDescriptor = fontDescriptor()
        let newFontDescriptor = oldFontDescriptor.monospacedDigitFontDescriptor

        return UIFont(descriptor: newFontDescriptor, size: 0)
    } else {
       return self
    }
}

или, просто используйте Helvetica. Он по-прежнему имеет моноширинные номера и работает ретроактивно к старой версии iOS.