web-dev-qa-db-ja.com

iOS 9のUILabelで等幅の数値を取得する方法

WWDC 2015で、新しい「San Francisco」システムフォントについてのセッションがありました iOS9。iOS9 SDKにリンクされている場合、デフォルトでは等幅の数値ではなく比例数レンダリングが使用されます。等幅の数値表示を明示的に有効にするために使用できるNSFont.monospacedDigitsSystemFontOfSize(mySize weight:)と呼ばれるNSFontの便利な初期化子があります。

しかし、UIKitでこれに相当するUIFontを見つけることができませんでした。

29
Samuel Mellert

便利な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 の最新バージョン。

40

これは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)
48
Ric Santos

Swift 4ではかなりの名前の変更があったため、属性は次のようになります。

    let fontDescriptorAttributes = [
        UIFontDescriptor.AttributeName.featureSettings: [
            [
                UIFontDescriptor.FeatureKey.featureIdentifier: kNumberSpacingType,
                UIFontDescriptor.FeatureKey.typeIdentifier: kMonospacedNumbersSelector
            ]
        ]
    ]
5
samwize

受け入れられたソリューションはうまく機能しますが、コンパイラの最適化をFast(リリースビルドのデフォルト)に設定するとクラッシュしました。このようにコードを書き直したが、今はそうではない:

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

注:現在受け入れられている回答のメソッドは、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)
    }
}
2
Jawwad

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
    }
}
0
OgreSwamp