Comment utiliser une police personnalisée avec des tailles de texte dynamiques dans iOS7

87

Dans iOS7, il existe de nouvelles API pour obtenir une police qui est automatiquement ajustée à la taille du texte que l'utilisateur a définie dans ses préférences.

Cela ressemble à quelque chose comme ça pour l'utiliser:

UIFont *myFont = [UIFont fontWithDescriptor:[UIFontDescriptor preferredFontDescriptorWithTextStyle:UIFontTextStyleHeadline] size:0];

Maintenant, quel que soit le texte auquel vous attribuez cela, la taille de la police augmentera et diminuera à mesure que l'utilisateur modifie le paramètre de taille de texte du système. (N'oubliez pas d'écouter la name:UIContentSizeCategoryDidChangeNotificationnotification et de mettre à jour votre vue pour tenir compte du changement de taille).

Comment utiliser du texte dynamique avec une police autre que Helvetica-Neue par défaut?

Bob Spryn
la source
N'est-il pas temps pour vous d'accepter une réponse?
Khanh Nguyen
À partir d'ios-11 +, Apple prend en charge l'utilisation de tailles de police dynamiques personnalisées. Pour la mise en œuvre, veuillez consulter cette réponse .
Umair Ali

Réponses:

132

Dans les coulisses de cette API, Apple a une sorte de table de recherche qui renvoie une famille de polices, une taille et parfois des traits symboliques spécifiques (comme le gras) qui (par exemple UIFontTextStyleHeadline) et la taille de texte préférée de l'utilisateur. Ce dernier est une chaîne tirée de la sharedApplicationsorte:

[UIApplication sharedApplication].preferredContentSizeCategory;

(J'ai déconnecté toutes les tailles / polices / traits par défaut pour Helvetica-Neue pour les différentes tailles de texte dynamiques). Depuis, nous avons ajouté la gestion des tailles d'accessibilité, ce qui est important .

Il vous suffit donc de créer une table de recherche similaire. Notre designer a créé une feuille de calcul simple pour moi:

Table de recherche de taille de police

Notez que nous avons ajouté quelques styles (légendes 3 et 4) pour en avoir 8 au lieu de 6.

Ensuite, vous voudrez le placer dans un endroit pratique, comme une catégorie UIFontDescriptor. Vous voudrez que votre méthode renvoie une UIFontDescriptorAPI similaire à celle d'Apple, de sorte qu'il soit toujours facile de l'ajuster avec des traits symboliques, etc.

Ma catégorie ressemble à ceci:

UIFontDescriptor + AvenirNext.h

#import <UIKit/UIKit.h>

extern NSString *const ANUIFontTextStyleCaption3;

@interface UIFontDescriptor (AvenirNext)

+(UIFontDescriptor *)preferredAvenirNextFontDescriptorWithTextStyle:(NSString *)style;

@end

UIFontDescriptor + AvenirNext.m

#import "UIFontDescriptor+AvenirNext.h"

NSString *const ANUIFontTextStyleCaption3 = @"ANUIFontTextStyleCaption3";
NSString *const ANUIFontTextStyleCaption4 = @"ANUIFontTextStyleCaption4";

@implementation UIFontDescriptor (AvenirNext)
+(UIFontDescriptor *)preferredAvenirNextFontDescriptorWithTextStyle:(NSString *)style {
    static dispatch_once_t onceToken;
    static NSDictionary *fontSizeTable;
    dispatch_once(&onceToken, ^{
        fontSizeTable = @{
          UIFontTextStyleHeadline: @{
                                    UIContentSizeCategoryAccessibilityExtraExtraExtraLarge: @26,
                                    UIContentSizeCategoryAccessibilityExtraExtraLarge: @25,
                                    UIContentSizeCategoryAccessibilityExtraLarge: @24,
                                    UIContentSizeCategoryAccessibilityLarge: @24,
                                    UIContentSizeCategoryAccessibilityMedium: @23,
                                    UIContentSizeCategoryExtraExtraExtraLarge: @23,
                                    UIContentSizeCategoryExtraExtraLarge: @22,
                                    UIContentSizeCategoryExtraLarge: @21,
                                    UIContentSizeCategoryLarge: @20,
                                    UIContentSizeCategoryMedium: @19,
                                    UIContentSizeCategorySmall: @18,
                                    UIContentSizeCategoryExtraSmall: @17,},

       UIFontTextStyleSubheadline: @{
                                    UIContentSizeCategoryAccessibilityExtraExtraExtraLarge: @24,
                                    UIContentSizeCategoryAccessibilityExtraExtraLarge: @23,
                                    UIContentSizeCategoryAccessibilityExtraLarge: @22,
                                    UIContentSizeCategoryAccessibilityLarge: @22,
                                    UIContentSizeCategoryAccessibilityMedium: @21,
                                    UIContentSizeCategoryExtraExtraExtraLarge: @21,
                                    UIContentSizeCategoryExtraExtraLarge: @20,
                                    UIContentSizeCategoryExtraLarge: @19,
                                    UIContentSizeCategoryLarge: @18,
                                    UIContentSizeCategoryMedium: @17,
                                    UIContentSizeCategorySmall: @16,
                                    UIContentSizeCategoryExtraSmall: @15,},

              UIFontTextStyleBody: @{
                                    UIContentSizeCategoryAccessibilityExtraExtraExtraLarge: @21,
                                    UIContentSizeCategoryAccessibilityExtraExtraLarge: @20,
                                    UIContentSizeCategoryAccessibilityExtraLarge: @19,
                                    UIContentSizeCategoryAccessibilityLarge: @19,
                                    UIContentSizeCategoryAccessibilityMedium: @18,
                                    UIContentSizeCategoryExtraExtraExtraLarge: @18,
                                    UIContentSizeCategoryExtraExtraLarge: @17,
                                    UIContentSizeCategoryExtraLarge: @16,
                                    UIContentSizeCategoryLarge: @15,
                                    UIContentSizeCategoryMedium: @14,
                                    UIContentSizeCategorySmall: @13,
                                    UIContentSizeCategoryExtraSmall: @12,},
          
          UIFontTextStyleCaption1: @{
                                    UIContentSizeCategoryAccessibilityExtraExtraExtraLarge: @19,
                                    UIContentSizeCategoryAccessibilityExtraExtraLarge: @18,
                                    UIContentSizeCategoryAccessibilityExtraLarge: @17,
                                    UIContentSizeCategoryAccessibilityLarge: @17,
                                    UIContentSizeCategoryAccessibilityMedium: @16,
                                    UIContentSizeCategoryExtraExtraExtraLarge: @16,
                                    UIContentSizeCategoryExtraExtraLarge: @16,
                                    UIContentSizeCategoryExtraLarge: @15,
                                    UIContentSizeCategoryLarge: @14,
                                    UIContentSizeCategoryMedium: @13,
                                    UIContentSizeCategorySmall: @12,
                                    UIContentSizeCategoryExtraSmall: @12,},
          
          UIFontTextStyleCaption2: @{
                                    UIContentSizeCategoryAccessibilityExtraExtraExtraLarge: @18,
                                    UIContentSizeCategoryAccessibilityExtraExtraLarge: @17,
                                    UIContentSizeCategoryAccessibilityExtraLarge: @16,
                                    UIContentSizeCategoryAccessibilityLarge: @16,
                                    UIContentSizeCategoryAccessibilityMedium: @15,
                                    UIContentSizeCategoryExtraExtraExtraLarge: @15,
                                    UIContentSizeCategoryExtraExtraLarge: @14,
                                    UIContentSizeCategoryExtraLarge: @14,
                                    UIContentSizeCategoryLarge: @13,
                                    UIContentSizeCategoryMedium: @12,
                                    UIContentSizeCategorySmall: @12,
                                    UIContentSizeCategoryExtraSmall: @11,},
          
        ANUIFontTextStyleCaption3: @{
                                    UIContentSizeCategoryAccessibilityExtraExtraExtraLarge: @17,
                                    UIContentSizeCategoryAccessibilityExtraExtraLarge: @16,
                                    UIContentSizeCategoryAccessibilityExtraLarge: @15,
                                    UIContentSizeCategoryAccessibilityLarge: @15,
                                    UIContentSizeCategoryAccessibilityMedium: @14,
                                    UIContentSizeCategoryExtraExtraExtraLarge: @14,
                                    UIContentSizeCategoryExtraExtraLarge: @13,
                                    UIContentSizeCategoryExtraLarge: @12,
                                    UIContentSizeCategoryLarge: @12,
                                    UIContentSizeCategoryMedium: @12,
                                    UIContentSizeCategorySmall: @11,
                                    UIContentSizeCategoryExtraSmall: @10,},

          UIFontTextStyleFootnote: @{
                                    UIContentSizeCategoryAccessibilityExtraExtraExtraLarge: @16,
                                    UIContentSizeCategoryAccessibilityExtraExtraLarge: @15,
                                    UIContentSizeCategoryAccessibilityExtraLarge: @14,
                                    UIContentSizeCategoryAccessibilityLarge: @14,
                                    UIContentSizeCategoryAccessibilityMedium: @13,
                                    UIContentSizeCategoryExtraExtraExtraLarge: @13,
                                    UIContentSizeCategoryExtraExtraLarge: @12,
                                    UIContentSizeCategoryExtraLarge: @12,
                                    UIContentSizeCategoryLarge: @11,
                                    UIContentSizeCategoryMedium: @11,
                                    UIContentSizeCategorySmall: @10,
                                    UIContentSizeCategoryExtraSmall: @10,},

          ANUIFontTextStyleCaption4: @{
                                    UIContentSizeCategoryAccessibilityExtraExtraExtraLarge: @15,
                                    UIContentSizeCategoryAccessibilityExtraExtraLarge: @14,
                                    UIContentSizeCategoryAccessibilityExtraLarge: @13,
                                    UIContentSizeCategoryAccessibilityLarge: @13,
                                    UIContentSizeCategoryAccessibilityMedium: @12,
                                    UIContentSizeCategoryExtraExtraExtraLarge: @12,
                                    UIContentSizeCategoryExtraExtraLarge: @11,
                                    UIContentSizeCategoryExtraLarge: @11,
                                    UIContentSizeCategoryLarge: @10,
                                    UIContentSizeCategoryMedium: @10,
                                    UIContentSizeCategorySmall: @9,
                                    UIContentSizeCategoryExtraSmall: @9,},
        };
    });
    
    
    NSString *contentSize = [UIApplication sharedApplication].preferredContentSizeCategory;
    return [UIFontDescriptor fontDescriptorWithName:[self preferredFontName] size:((NSNumber *)fontSizeTable[style][contentSize]).floatValue];
}
+(UIFontDescriptor *)preferredAvenirNextDemiBoldFontDescriptorWithTextStyle:(NSString *)style {
    return [[self preferredAvenirNextFontDescriptorWithTextStyle:style] fontDescriptorWithSymbolicTraits:UIFontDescriptorTraitBold];
}

+(UIFontDescriptor *)preferredAvenirNextBoldFontDescriptorWithTextStyle:(NSString *)style {
    return [UIFontDescriptor fontDescriptorWithName:[self preferredBoldFontName] size:[self preferredAvenirNextFontDescriptorWithTextStyle:style].pointSize];
}

+(NSString *)preferredFontName {
    return @"AvenirNext-Medium";
}
+(NSString *)preferredBoldFontName {
    return @"AvenirNext-Bold";
}

@end

Nous avons choisi d'utiliser la même police de base AvenirNext-Medium, puis gras et autres via des traits symboliques, mais vous pourriez devenir fou et spécifier différentes variantes de poids sur votre police dans le cadre de votre table de recherche si vous le souhaitez, par exemple AvenirNext-ExtraBold.

C'est tout ce qu'on peut en dire! Nous l'utilisons comme ceci:

[UIFont fontWithDescriptor:[UIFontDescriptor preferredAvenirNextFontDescriptorWithTextStyle:UIFontTextStyleHeadline] size: 0]
Bob Spryn
la source
6
Une excellente solution, mais vous manquez les constantes d'accessibilité: UIContentSizeCategoryAccessibilityMedium, UIContentSizeCategoryAccessibilityLarge, etc.
Ben Jackson
Ah intéressant. Bon à savoir @BenJackson. Merci!
Bob Spryn
1
Pourquoi ne pas étendre UIFont, pour pouvoir simplement utiliser [UIFont preferredAvenirFontForTextStyle:UIFontTextStyleHeadline]:? La taille est redondante dans l'exemple que vous donnez en bas?
cleverbit
2
@richarddas simplement pour suivre le modèle d'Apple. Une taille de 0 est ignorée et passe simplement par la taille correcte du descripteur.
Bob Spryn
4
À partir d'iOS 8.4, Apple a légèrement modifié les tailles de police: gist.github.com/klaas/750f489e2390389ab812
Klaas
15

C'est comme ça que je le fais dans Swift. J'aime cela parce que c'est plus général, cela ne nécessite qu'une seule table et cela devrait bien fonctionner avec n'importe quelle police. J'ai d'abord écrit un multiplicateur généralisé (dans un getter).

var fontSizeMultiplier : CGFloat {
    get {
        switch UIApplication.sharedApplication().preferredContentSizeCategory {
        case UIContentSizeCategoryAccessibilityExtraExtraExtraLarge: return 23 / 16
        case UIContentSizeCategoryAccessibilityExtraExtraLarge: return 22 / 16
        case UIContentSizeCategoryAccessibilityExtraLarge: return 21 / 16
        case UIContentSizeCategoryAccessibilityLarge: return 20 / 16
        case UIContentSizeCategoryAccessibilityMedium: return 19 / 16
        case UIContentSizeCategoryExtraExtraExtraLarge: return 19 / 16
        case UIContentSizeCategoryExtraExtraLarge: return 18 / 16
        case UIContentSizeCategoryExtraLarge: return 17 / 16
        case UIContentSizeCategoryLarge: return 1.0
        case UIContentSizeCategoryMedium: return 15 / 16
        case UIContentSizeCategorySmall: return 14 / 16
        case UIContentSizeCategoryExtraSmall: return 13 / 16
        default: return 1.0
        }
    }
}

Ensuite, je mets à jour la police (par exemple, dans l'observateur) en utilisant un UIFontDescriptorcomme ceci:

textView.font = UIFont(descriptor: fontDescriptor!, size: fontDescriptor!.pointSize * fontSizeMultiplier)
Bill Weinman
la source
Cela ne fonctionnera pas car le pointSize augmentera de façon exponentielle chaque fois que vous mettez à jour la taille dans les paramètres. Si vous définissez une taille de police par défaut, vous pouvez l'utiliser comme base et la multiplier par fontSizeMultiplier.
TejAces
@TejAces - Cela fonctionne bien. Je l'utilise depuis des années. Puisqu'il renvoie des valeurs littérales, je ne vois pas comment vous pensez qu'il augmenterait lorsque vous modifiez les paramètres.
Bill Weinman
12

Dans iOS 11, la UIFontMetricsclasse a été introduite. Créez un objet FontMetrics pour le style de texte qui vous intéresse. Choisissez ensuite la police de votre choix, dimensionnée pour la taille de texte dynamique standard. Ensuite, vous pouvez demander à l'objet FontMetrics de redimensionner cette police en fonction des paramètres actuels de l'utilisateur.

let bodyMetrics = UIFontMetrics(forTextStyle: .body)
let standardFont = ... // any font you want, for standard type size
let font = bodyMetrics.scaledFont(for: standardFont)
ceinture
la source
8

Code @Bob Spryn réécrit avec Swift:

import UIKit

extension UIFontDescriptor {

    private struct SubStruct {
        static var preferredFontName: NSString = "OEMeodedPashutPro-Regular"
    }

    class func preferredDescriptor(textStyle: NSString) -> UIFontDescriptor {
        struct Static {
            static var onceToken : dispatch_once_t = 0
            static var fontSizeTable : NSDictionary = NSDictionary()
        }

        dispatch_once(&Static.onceToken) {
            Static.fontSizeTable = [
                UIFontTextStyleHeadline: [
                    UIContentSizeCategoryAccessibilityExtraExtraExtraLarge: 26,
                    UIContentSizeCategoryAccessibilityExtraExtraLarge: 25,
                    UIContentSizeCategoryAccessibilityExtraLarge: 24,
                    UIContentSizeCategoryAccessibilityLarge: 24,
                    UIContentSizeCategoryAccessibilityMedium: 23,
                    UIContentSizeCategoryExtraExtraExtraLarge: 23,
                    UIContentSizeCategoryExtraExtraLarge: 22,
                    UIContentSizeCategoryExtraLarge: 21,
                    UIContentSizeCategoryLarge: 20,
                    UIContentSizeCategoryMedium: 19,
                    UIContentSizeCategorySmall: 18,
                    UIContentSizeCategoryExtraSmall: 17
                ],
                UIFontTextStyleSubheadline: [
                    UIContentSizeCategoryAccessibilityExtraExtraExtraLarge: 24,
                    UIContentSizeCategoryAccessibilityExtraExtraLarge: 23,
                    UIContentSizeCategoryAccessibilityExtraLarge: 22,
                    UIContentSizeCategoryAccessibilityLarge: 22,
                    UIContentSizeCategoryAccessibilityMedium: 21,
                    UIContentSizeCategoryExtraExtraExtraLarge: 21,
                    UIContentSizeCategoryExtraExtraLarge: 20,
                    UIContentSizeCategoryExtraLarge: 19,
                    UIContentSizeCategoryLarge: 18,
                    UIContentSizeCategoryMedium: 17,
                    UIContentSizeCategorySmall: 16,
                    UIContentSizeCategoryExtraSmall: 15
                ],
                UIFontTextStyleBody: [
                    UIContentSizeCategoryAccessibilityExtraExtraExtraLarge: 21,
                    UIContentSizeCategoryAccessibilityExtraExtraLarge: 20,
                    UIContentSizeCategoryAccessibilityExtraLarge: 19,
                    UIContentSizeCategoryAccessibilityLarge: 19,
                    UIContentSizeCategoryAccessibilityMedium: 18,
                    UIContentSizeCategoryExtraExtraExtraLarge: 18,
                    UIContentSizeCategoryExtraExtraLarge: 17,
                    UIContentSizeCategoryExtraLarge: 16,
                    UIContentSizeCategoryLarge: 15,
                    UIContentSizeCategoryMedium: 14,
                    UIContentSizeCategorySmall: 13,
                    UIContentSizeCategoryExtraSmall: 12
                ],
                UIFontTextStyleCaption1: [
                    UIContentSizeCategoryAccessibilityExtraExtraExtraLarge: 19,
                    UIContentSizeCategoryAccessibilityExtraExtraLarge: 18,
                    UIContentSizeCategoryAccessibilityExtraLarge: 17,
                    UIContentSizeCategoryAccessibilityLarge: 17,
                    UIContentSizeCategoryAccessibilityMedium: 16,
                    UIContentSizeCategoryExtraExtraExtraLarge: 16,
                    UIContentSizeCategoryExtraExtraLarge: 16,
                    UIContentSizeCategoryExtraLarge: 15,
                    UIContentSizeCategoryLarge: 14,
                    UIContentSizeCategoryMedium: 13,
                    UIContentSizeCategorySmall: 12,
                    UIContentSizeCategoryExtraSmall: 12
                ],
                UIFontTextStyleCaption2: [
                    UIContentSizeCategoryAccessibilityExtraExtraExtraLarge: 18,
                    UIContentSizeCategoryAccessibilityExtraExtraLarge: 17,
                    UIContentSizeCategoryAccessibilityExtraLarge: 16,
                    UIContentSizeCategoryAccessibilityLarge: 16,
                    UIContentSizeCategoryAccessibilityMedium: 15,
                    UIContentSizeCategoryExtraExtraExtraLarge: 15,
                    UIContentSizeCategoryExtraExtraLarge: 14,
                    UIContentSizeCategoryExtraLarge: 14,
                    UIContentSizeCategoryLarge: 13,
                    UIContentSizeCategoryMedium: 12,
                    UIContentSizeCategorySmall: 12,
                    UIContentSizeCategoryExtraSmall: 11
                ],
                UIFontTextStyleFootnote: [
                    UIContentSizeCategoryAccessibilityExtraExtraExtraLarge: 16,
                    UIContentSizeCategoryAccessibilityExtraExtraLarge: 15,
                    UIContentSizeCategoryAccessibilityExtraLarge: 14,
                    UIContentSizeCategoryAccessibilityLarge: 14,
                    UIContentSizeCategoryAccessibilityMedium: 13,
                    UIContentSizeCategoryExtraExtraExtraLarge: 13,
                    UIContentSizeCategoryExtraExtraLarge: 12,
                    UIContentSizeCategoryExtraLarge: 12,
                    UIContentSizeCategoryLarge: 11,
                    UIContentSizeCategoryMedium: 11,
                    UIContentSizeCategorySmall: 10,
                    UIContentSizeCategoryExtraSmall: 10
                ],
            ]
        }

        let contentSize = UIApplication.sharedApplication().preferredContentSizeCategory

        let style = Static.fontSizeTable[textStyle] as NSDictionary

        return UIFontDescriptor(name: SubStruct.preferredFontName, size: CGFloat((style[contentSize] as NSNumber).floatValue))
    }

}

Usage:

UIFont(descriptor: UIFontDescriptor.preferredDescriptor(UIFontTextStyleBody), size: 0)
smartDonkey
la source
1
Xcode 7.2 m'a fait changer les deux dernières lignes en: let style = Static.fontSizeTable[textStyle] as! NSDictionaryetreturn UIFontDescriptor(name: SubStruct.preferredFontName as String, size: CGFloat((style[contentSize] as! NSNumber).floatValue))
koen
Ce serait vraiment cool si je pouvais faire quelque chose qui montre la police préférée dans Storyboard. Peut-être en sous-classant les éléments de texte.
Aaron Bratcher le
7

Essaye ça:

UIFontDescriptor *userHeadLineFont = [UIFontDescriptor preferredFontDescriptorWithTextStyle:UIFontTextStyleHeadline];
CGFloat userHeadLineFontSize = [userHeadLineFont pointSize];
myFont = [UIFont fontWithName:@"Baskerville" size:userHeadLineFontSize];

Mais gardez à l'esprit que ce code n'est qu'une approximation (le type dynamique fait bien plus que simplement mettre à l'échelle la taille de la police).

Valfer
la source
Pouvez-vous élaborer sur la paranthèse? Que dois-je prendre en compte de plus que la mise à l'échelle?
hfossli
2
Il existe une correspondance entre la police "type dynamique" et la police réellement utilisée. Par exemple, une petite police peut devenir grasse. Je ne connais pas la cartographie exacte. Voir la dernière image ("mise à l'échelle optique de type dynamique") dans cet article: fireballed.org/linked/2013/07/08/ios-7-type pour mieux comprendre.
valfer
1
Celui-ci fait la même chose que la bonne réponse approuvée, mais une sorte de différence dans le nombre de lignes. Excellente solution. La même chose dans SWIFT stackoverflow.com/questions/35355695/…
Vanya
Voici un lien de travail vers l'article mentionné par @valfer dans les commentaires: Beyond Helvetica: The Real Story Behind Fonts in iOS 7
0xced le
6

Semblable à l'approche de @ bill-weinman , j'ai pris la balance et je l'ai divisée en une fonction qui ne repose pas sur une taille de police donnée de 16.

/// The font scale for a given font size.
///
/// - seealso: [Source](https://stackoverflow.com/a/33114525/3643020)
///
/// - Parameter fontSize: The font size.
/// - Returns: The font scale
public func fontScale(for fontSize: CGFloat) -> CGFloat {
    switch UIApplication.shared.preferredContentSizeCategory {
    case UIContentSizeCategory.accessibilityExtraExtraExtraLarge:    return (fontSize + 8) / fontSize
    case UIContentSizeCategory.accessibilityExtraExtraLarge:         return (fontSize + 7) / fontSize
    case UIContentSizeCategory.accessibilityExtraLarge:              return (fontSize + 6) / fontSize
    case UIContentSizeCategory.accessibilityLarge:                   return (fontSize + 5) / fontSize
    case UIContentSizeCategory.accessibilityMedium:                  return (fontSize + 4) / fontSize
    case UIContentSizeCategory.extraExtraExtraLarge:                 return (fontSize + 3) / fontSize
    case UIContentSizeCategory.extraExtraLarge:                      return (fontSize + 2) / fontSize
    case UIContentSizeCategory.extraLarge:                           return (fontSize + 1) / fontSize
    case UIContentSizeCategory.large:                                return 1.0
    case UIContentSizeCategory.medium:                               return (fontSize - 1) / fontSize
    case UIContentSizeCategory.small:                                return (fontSize - 2) / fontSize
    case UIContentSizeCategory.extraSmall:                           return (fontSize - 3) / fontSize
    default:
        return 1.0
    }
}

Il peut ensuite être utilisé avec des polices personnalisées comme celle-ci:

/// Light font of specified size.
///
/// - Parameter size: Font size.
/// - Returns: Light font of specified size.
func lightFont(ofSize size: CGFloat) -> UIFont {
    let scaledSize = size * fontScale(for: size)

    return UIFont(name: "HelveticaNeueLTStd-Lt", size: scaledSize)!
}
Campbell_Souped
la source
Ce n'est pas mal si vous êtes à un stade où vous ne voulez pas tout régler. Aussi si votre police personnalisée est plutôt petite et nécessite une mise à l'échelle par défaut.
JanBrinker du
FYI - mon approche ne repose pas sur la taille de la police. Il renvoie une valeur basée sur un ratio. Cela fonctionne très bien avec les polices personnalisées / mises à l'échelle.
Bill Weinman
3

Dans iOS 11, vous pouvez utiliser:

var customFont = UIFont.systemFont(ofSize: 17.0)
if #available(iOS 11.0, *) {
    customFont = UIFontMetrics.default.scaledFont(for: customFont)
}
// use customFont...

Voir aussi Création d'applications avec Dynamic Type WWDC 2017 - Session 245 - heure iOS 8:34.

Petrsyn
la source
2

Code Swift 2.1-3.0 basé sur le port de @ smartDonkey du code @Bob Spryn. Également mis à jour avec les tailles Apple de @Klaas .

import UIKit

extension UIFontDescriptor {

    private struct SubStruct {
        static var preferredFontName: String = "Roboto-Light"
    }

    class func preferredDescriptor(textStyle: NSString) -> UIFontDescriptor {
        struct Static {
            static var onceToken : dispatch_once_t = 0
            static var fontSizeTable : NSDictionary = NSDictionary()
        }

        dispatch_once(&Static.onceToken) {
            Static.fontSizeTable = [
                UIFontTextStyleHeadline: [
                    UIContentSizeCategoryAccessibilityExtraExtraExtraLarge: 23,
                    UIContentSizeCategoryAccessibilityExtraExtraLarge: 23,
                    UIContentSizeCategoryAccessibilityExtraLarge: 23,
                    UIContentSizeCategoryAccessibilityLarge: 23,
                    UIContentSizeCategoryAccessibilityMedium: 23,
                    UIContentSizeCategoryExtraExtraExtraLarge: 23,
                    UIContentSizeCategoryExtraExtraLarge: 21,
                    UIContentSizeCategoryExtraLarge: 19,
                    UIContentSizeCategoryLarge: 17,
                    UIContentSizeCategoryMedium: 16,
                    UIContentSizeCategorySmall: 15,
                    UIContentSizeCategoryExtraSmall: 14
                ],
                UIFontTextStyleSubheadline: [
                    UIContentSizeCategoryAccessibilityExtraExtraExtraLarge: 21,
                    UIContentSizeCategoryAccessibilityExtraExtraLarge: 21,
                    UIContentSizeCategoryAccessibilityExtraLarge: 21,
                    UIContentSizeCategoryAccessibilityLarge: 21,
                    UIContentSizeCategoryAccessibilityMedium: 21,
                    UIContentSizeCategoryExtraExtraExtraLarge: 21,
                    UIContentSizeCategoryExtraExtraLarge: 19,
                    UIContentSizeCategoryExtraLarge: 17,
                    UIContentSizeCategoryLarge: 15,
                    UIContentSizeCategoryMedium: 14,
                    UIContentSizeCategorySmall: 13,
                    UIContentSizeCategoryExtraSmall: 12
                ],
                UIFontTextStyleBody: [
                    UIContentSizeCategoryAccessibilityExtraExtraExtraLarge: 53,
                    UIContentSizeCategoryAccessibilityExtraExtraLarge: 47,
                    UIContentSizeCategoryAccessibilityExtraLarge: 40,
                    UIContentSizeCategoryAccessibilityLarge: 33,
                    UIContentSizeCategoryAccessibilityMedium: 28,
                    UIContentSizeCategoryExtraExtraExtraLarge: 23,
                    UIContentSizeCategoryExtraExtraLarge: 21,
                    UIContentSizeCategoryExtraLarge: 19,
                    UIContentSizeCategoryLarge: 17,
                    UIContentSizeCategoryMedium: 16,
                    UIContentSizeCategorySmall: 15,
                    UIContentSizeCategoryExtraSmall: 14
                ],
                UIFontTextStyleCaption1: [
                    UIContentSizeCategoryAccessibilityExtraExtraExtraLarge: 18,
                    UIContentSizeCategoryAccessibilityExtraExtraLarge: 18,
                    UIContentSizeCategoryAccessibilityExtraLarge: 18,
                    UIContentSizeCategoryAccessibilityLarge: 18,
                    UIContentSizeCategoryAccessibilityMedium: 18,
                    UIContentSizeCategoryExtraExtraExtraLarge: 18,
                    UIContentSizeCategoryExtraExtraLarge: 16,
                    UIContentSizeCategoryExtraLarge: 14,
                    UIContentSizeCategoryLarge: 12,
                    UIContentSizeCategoryMedium: 11,
                    UIContentSizeCategorySmall: 11,
                    UIContentSizeCategoryExtraSmall: 11
                ],
                UIFontTextStyleCaption2: [
                    UIContentSizeCategoryAccessibilityExtraExtraExtraLarge: 17,
                    UIContentSizeCategoryAccessibilityExtraExtraLarge: 17,
                    UIContentSizeCategoryAccessibilityExtraLarge: 17,
                    UIContentSizeCategoryAccessibilityLarge: 17,
                    UIContentSizeCategoryAccessibilityMedium: 17,
                    UIContentSizeCategoryExtraExtraExtraLarge: 17,
                    UIContentSizeCategoryExtraExtraLarge: 15,
                    UIContentSizeCategoryExtraLarge: 13,
                    UIContentSizeCategoryLarge: 11,
                    UIContentSizeCategoryMedium: 11,
                    UIContentSizeCategorySmall: 11,
                    UIContentSizeCategoryExtraSmall: 11
                ],
                UIFontTextStyleFootnote: [
                    UIContentSizeCategoryAccessibilityExtraExtraExtraLarge: 19,
                    UIContentSizeCategoryAccessibilityExtraExtraLarge: 19,
                    UIContentSizeCategoryAccessibilityExtraLarge: 19,
                    UIContentSizeCategoryAccessibilityLarge: 19,
                    UIContentSizeCategoryAccessibilityMedium: 19,
                    UIContentSizeCategoryExtraExtraExtraLarge: 19,
                    UIContentSizeCategoryExtraExtraLarge: 17,
                    UIContentSizeCategoryExtraLarge: 15,
                    UIContentSizeCategoryLarge: 13,
                    UIContentSizeCategoryMedium: 12,
                    UIContentSizeCategorySmall: 12,
                    UIContentSizeCategoryExtraSmall: 12
                ],
            ]
        }

        let contentSize = UIApplication.sharedApplication().preferredContentSizeCategory
        let style = Static.fontSizeTable[textStyle] as! NSDictionary
        return UIFontDescriptor(name: SubStruct.preferredFontName, size: CGFloat((style[contentSize] as! NSNumber).floatValue))
    }

}
Gobe
la source
Erreurs sur Swift 3 avec votre solution:'dispatch_once_t' is unavailable in Swift: Use lazily initialized globals instead
thexande
1

Voici comment je mets à jour la police d'un prefferedFontForTextStyle:

UIFont *font = [UIFont preferredFontForTextStyle:UIFontTextStyleBody];
UIFontDescriptor *fontDesc = [font fontDescriptor];
fontDesc = [fontDesc fontDescriptorByAddingAttributes:@{UIFontDescriptorNameAttribute : @"Helvetica",
                                                        UIFontDescriptorSizeAttribute : @16}];

font = [UIFont fontWithDescriptor:fontDesc
                             size:[fontDesc pointSize]];
Oleg Danu
la source
1

Je voulais juste intervenir et dire qu'il existe une bibliothèque pour aider à intégrer des polices personnalisées et gérer les changements de taille de type dynamique. Il s'appelle, utilement, Font ( https://github.com/adamyanalunas/Font ) et au lieu d'être une solution magique, il met en place une structure pour gérer chaque police personnalisée différemment tout en supprimant le passe-partout.

nb je suis l'auteur de cette petite bibliothèque et je trouve que c'est chouette.

Adam Yanalunas
la source
1

Voici mon point de vue sur la réponse de @ Gobe, dans Swift 3:

extension UIFontDescriptor {

@nonobjc static var fontSizeTable: [UIFontTextStyle : [UIContentSizeCategory : CGFloat]] = {
    return [
        .headline: [
            .accessibilityExtraExtraExtraLarge: 23,
            .accessibilityExtraExtraLarge: 23,
            .accessibilityExtraLarge: 23,
            .accessibilityLarge: 23,
            .accessibilityMedium: 23,
            .extraExtraExtraLarge: 23,
            .extraExtraLarge: 21,
            .extraLarge: 19,
            .large: 17,
            .medium: 16,
            .small: 15,
            .extraSmall: 14],
        .subheadline: [
            .accessibilityExtraExtraExtraLarge: 21,
            .accessibilityExtraExtraLarge: 21,
            .accessibilityExtraLarge: 21,
            .accessibilityLarge: 21,
            .accessibilityMedium: 21,
            .extraExtraExtraLarge: 21,
            .extraExtraLarge: 19,
            .extraLarge: 17,
            .large: 15,
            .medium: 14,
            .small: 13,
            .extraSmall: 12],
        .body: [
            .accessibilityExtraExtraExtraLarge: 53,
            .accessibilityExtraExtraLarge: 47,
            .accessibilityExtraLarge: 40,
            .accessibilityLarge: 33,
            .accessibilityMedium: 28,
            .extraExtraExtraLarge: 23,
            .extraExtraLarge: 21,
            .extraLarge: 19,
            .large: 17,
            .medium: 16,
            .small: 15,
            .extraSmall: 14],
        .caption1: [
            .accessibilityExtraExtraExtraLarge: 18,
            .accessibilityExtraExtraLarge: 18,
            .accessibilityExtraLarge: 18,
            .accessibilityLarge: 18,
            .accessibilityMedium: 18,
            .extraExtraExtraLarge: 18,
            .extraExtraLarge: 16,
            .extraLarge: 14,
            .large: 12,
            .medium: 11,
            .small: 11,
            .extraSmall: 11],
        .caption2: [
            .accessibilityExtraExtraExtraLarge: 17,
            .accessibilityExtraExtraLarge: 17,
            .accessibilityExtraLarge: 17,
            .accessibilityLarge: 17,
            .accessibilityMedium: 17,
            .extraExtraExtraLarge: 17,
            .extraExtraLarge: 15,
            .extraLarge: 13,
            .large: 11,
            .medium: 11,
            .small: 11,
            .extraSmall: 11],
        .footnote: [
            .accessibilityExtraExtraExtraLarge: 19,
            .accessibilityExtraExtraLarge: 19,
            .accessibilityExtraLarge: 19,
            .accessibilityLarge: 19,
            .accessibilityMedium: 19,
            .extraExtraExtraLarge: 19,
            .extraExtraLarge: 17,
            .extraLarge: 15,
            .large: 13,
            .medium: 12,
            .small: 12,
            .extraSmall: 12],
    ]
}()

class func currentPreferredSize(textStyle: UIFontTextStyle = .body) -> CGFloat {
    let contentSize = UIApplication.shared.preferredContentSizeCategory
    guard let style = fontSizeTable[textStyle], let fontSize = style[contentSize] else { return 17 }
    return fontSize
}

class func preferredFontDescriptor(fontName: String = "SnellRoundhand", textStyle: UIFontTextStyle = .body) -> UIFontDescriptor {
    return UIFontDescriptor(name: fontName, size: currentPreferredSize())
}
}
Joshua Kaden
la source
0

À partir d'iOS 11, vous pouvez ajuster par programme les polices personnalisées configurées dans l'éditeur visuel:

  1. Configurez votre police personnalisée à l'aide de l'éditeur visuel
  2. Ajustez la taille de la police dans la méthode viewDidLoad:
@IBOutlet weak var leftLangLabel: UILabel!

override func viewDidLoad() {
    super.viewDidLoad()

    leftLangLabel.font = UIFontMetrics.default.scaledFont(for: leftLangLabel.font)
}
AlexeyVMP
la source