How to get monospaced numbers in UILabel on iOS 9
Handy UIFont
extension:
extension UIFont {
var monospacedDigitFont: UIFont {
let newFontDescriptor = fontDescriptor.monospacedDigitFontDescriptor
return UIFont(descriptor: newFontDescriptor, size: 0)
}
}
private extension UIFontDescriptor {
var monospacedDigitFontDescriptor: UIFontDescriptor {
let fontDescriptorFeatureSettings = [[UIFontDescriptor.FeatureKey.featureIdentifier: kNumberSpacingType,
UIFontDescriptor.FeatureKey.typeIdentifier: kMonospacedNumbersSelector]]
let fontDescriptorAttributes = [UIFontDescriptor.AttributeName.featureSettings: fontDescriptorFeatureSettings]
let fontDescriptor = self.addingAttributes(fontDescriptorAttributes)
return fontDescriptor
}
}
Usage with @IBOutlet
properties:
@IBOutlet private var timeLabel: UILabel? {
didSet {
timeLabel.font = timeLabel.font.monospacedDigitFont
}
}
Latest version on GitHub.
This is now available in UIFont
since iOS 9:
+ (UIFont *)monospacedDigitSystemFontOfSize:(CGFloat)fontSize weight:(CGFloat)weight NS_AVAILABLE_IOS(9_0);
eg:
[UIFont monospacedDigitSystemFontOfSize:42.0 weight:UIFontWeightMedium];
or in Swift:
UIFont.monospacedDigitSystemFont(ofSize: 42.0, weight: UIFontWeightMedium)
There has been quite some renaming in Swift 4, so the attributes now looks like this:
let fontDescriptorAttributes = [
UIFontDescriptor.AttributeName.featureSettings: [
[
UIFontDescriptor.FeatureKey.featureIdentifier: kNumberSpacingType,
UIFontDescriptor.FeatureKey.typeIdentifier: kMonospacedNumbersSelector
]
]
]
Accepted solution works great, but was crashing with compiler optimization set to Fast(default for Release builds). Rewrote the code like this and now it does not:
extension UIFont
{
var monospacedDigitFont: UIFont
{
return UIFont(descriptor: fontDescriptor().fontDescriptorByAddingAttributes([UIFontDescriptorFeatureSettingsAttribute: [[UIFontFeatureTypeIdentifierKey: kNumberSpacingType, UIFontFeatureSelectorIdentifierKey: kMonospacedNumbersSelector]]]), size: 0)
}
}