Подтвердить что ты не робот

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

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

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

4b9b3361

Ответ 1

Удобное расширение UIFont:

extension UIFont {

    var monospacedDigitFont: UIFont {
        let oldFontDescriptor = fontDescriptor()
        let newFontDescriptor = oldFontDescriptor.monospacedDigitFontDescriptor
        return UIFont(descriptor: newFontDescriptor, size: 0)
    }

}

private extension UIFontDescriptor {

    var monospacedDigitFontDescriptor: UIFontDescriptor {
        let fontDescriptorFeatureSettings = [[UIFontFeatureTypeIdentifierKey: kNumberSpacingType, UIFontFeatureSelectorIdentifierKey: kMonospacedNumbersSelector]]
        let fontDescriptorAttributes = [UIFontDescriptorFeatureSettingsAttribute: fontDescriptorFeatureSettings]
        let fontDescriptor = self.fontDescriptorByAddingAttributes(fontDescriptorAttributes)
        return fontDescriptor
    }

}

Использование свойств @IBOutlet:

@IBOutlet private var timeLabel: UILabel? {
    didSet {
        timeLabel.font = timeLabel.font.monospacedDigitFont
    }
}

Последняя версия на GitHub.

Ответ 2

Теперь это доступно в 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)

Ответ 3

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

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

Ответ 4

Примечание. Метод в принятом в настоящее время ответе начал сбой для меня в Xcode 7.3 (Swift 2.2), только в версиях Release. Исключение промежуточной переменной расширения 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)
    }
}

Ответ 5

Немного улучшенная версия кода @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
    }
}

Ответ 6

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