WWDC 2015で、新しい「San Francisco」システムフォントについてのセッションがありました iOS9。iOS9 SDKにリンクされている場合、デフォルトでは等幅の数値ではなく比例数レンダリングが使用されます。等幅の数値表示を明示的に有効にするために使用できるNSFont.monospacedDigitsSystemFontOfSize(mySize weight:)
と呼ばれるNSFontの便利な初期化子があります。
しかし、UIKit
でこれに相当するUIFont
を見つけることができませんでした。
便利なUIFont
拡張:
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
}
}
@IBOutlet
プロパティでの使用:
@IBOutlet private var timeLabel: UILabel? {
didSet {
timeLabel.font = timeLabel.font.monospacedDigitFont
}
}
GitHub の最新バージョン。
これはiOS 9以降、UIFont
で利用できるようになりました。
+ (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)
Swift 4ではかなりの名前の変更があったため、属性は次のようになります。
let fontDescriptorAttributes = [
UIFontDescriptor.AttributeName.featureSettings: [
[
UIFontDescriptor.FeatureKey.featureIdentifier: kNumberSpacingType,
UIFontDescriptor.FeatureKey.typeIdentifier: kMonospacedNumbersSelector
]
]
]
受け入れられたソリューションはうまく機能しますが、コンパイラの最適化をFast(リリースビルドのデフォルト)に設定するとクラッシュしました。このようにコードを書き直したが、今はそうではない:
extension UIFont
{
var monospacedDigitFont: UIFont
{
return UIFont(descriptor: fontDescriptor().fontDescriptorByAddingAttributes([UIFontDescriptorFeatureSettingsAttribute: [[UIFontFeatureTypeIdentifierKey: kNumberSpacingType, UIFontFeatureSelectorIdentifierKey: kMonospacedNumbersSelector]]]), size: 0)
}
}
注:現在受け入れられている回答のメソッドは、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)
}
}
IOSバージョンをチェックする@Rudolf Adamkovicコードの少し改良されたバージョン:
var monospacedDigitFont: UIFont {
if #available(iOS 9, *) {
let oldFontDescriptor = fontDescriptor()
let newFontDescriptor = oldFontDescriptor.monospacedDigitFontDescriptor
return UIFont(descriptor: newFontDescriptor, size: 0)
} else {
return self
}
}