问题
At WWDC 2015, there was a session about the new “San Francisco” system font in iOS 9. It uses proportional number rendering instead of monospaced numbers by default when linked against the iOS 9 SDK. There is a convenient initializer on NSFont called NSFont.monospacedDigitsSystemFontOfSize(mySize weight:)
that can be used to explicitly enable monospaced number display.
However I couldn't find the UIKit
equivalent for this on UIFont
.
回答1:
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.
回答2:
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)
回答3:
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)
}
}
回答4:
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
]
]
]
回答5:
Note: The method in the currently accepted answer has started crashing for me in Xcode 7.3 (Swift 2.2), only in Release builds. Eliminating the intermediary monospacedDigitFontDescriptor
extension variable fixes the issue.
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)
}
}
回答6:
A bit improved version of the @Rudolf Adamkovic code which checks iOS version:
var monospacedDigitFont: UIFont {
if #available(iOS 9, *) {
let oldFontDescriptor = fontDescriptor()
let newFontDescriptor = oldFontDescriptor.monospacedDigitFontDescriptor
return UIFont(descriptor: newFontDescriptor, size: 0)
} else {
return self
}
}
回答7:
Or, just use Helvetica. It still has monospaced numbers and works retroactively to older iOS version.
来源:https://stackoverflow.com/questions/30854690/how-to-get-monospaced-numbers-in-uilabel-on-ios-9