web-dev-qa-db-fra.com

Comment obtenir des numéros à espacement fixe dans UILabel sur iOS 9

Lors de la WWDC 2015, il y avait une session sur la nouvelle police système «San Francisco» sous iOS 9. Il utilise le rendu par nombre proportionnel au lieu de numéros à espacement fixe par défaut lorsqu'il est lié au SDK iOS 9. Il existe un initialiseur pratique sur NSFont appelé NSFont.monospacedDigitsSystemFontOfSize(mySize weight:) qui peut être utilisé pour activer explicitement l’affichage de numéros à un espace.

Cependant, je n'ai pas pu trouver l'équivalent UIKit pour ceci sur UIFont.

27
Samuel Mellert

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

Utilisation avec les propriétés @IBOutlet:

@IBOutlet private var timeLabel: UILabel? {
    didSet {
        timeLabel.font = timeLabel.font.monospacedDigitFont
    }
}

Dernière version sur GitHub .

38
Rudolf Adamkovič

Ceci est maintenant disponible dans UIFont depuis iOS 9:

+ (UIFont *)monospacedDigitSystemFontOfSize:(CGFloat)fontSize weight:(CGFloat)weight NS_AVAILABLE_IOS(9_0);

par exemple:

[UIFont monospacedDigitSystemFontOfSize:42.0 weight:UIFontWeightMedium];

ou à Swift:

UIFont.monospacedDigitSystemFont(ofSize: 42.0, weight: UIFontWeightMedium)
47
Ric Santos

Il y a eu pas mal de changements de nom dans Swift 4, donc les attributs ressemblent maintenant à ceci:

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

La solution acceptée fonctionne très bien, mais le blocage de l'optimisation du compilateur était défini sur Rapide (par défaut pour les versions Release). Réécrivez le code comme ceci et maintenant ce n'est pas le cas:

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

Remarque: La méthode dans la réponse actuellement acceptée a commencé à planter dans Xcode 7.3 (Swift 2.2), uniquement dans les versions Release. L'élimination de la variable d'extension intermédiaire monospacedDigitFontDescriptor résout le problème.

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

Version légèrement améliorée du code @Rudolf Adamkovic qui vérifie la version iOS:

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