Как получить моноширинные номера в UILabel на iOS 9
На WWDC 2015 был сеанс о новом системном шрифте San Francisco в iOS 9. Он использует рендеринг пропорционального числа вместо моноширинные номера по умолчанию при соединении с SDK iOS 9. В NSFont имеется удобный инициализатор под названием NSFont.monospacedDigitsSystemFontOfSize(mySize weight:)
, который может использоваться для явного включения отображения моноширинного номера.
Однако я не смог найти эквивалент UIKit
для этого на UIFont
.
Ответы
Ответ 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.