Font Descriptor : concepts clés et capacités du descripteur de police

Auteur : IT Sectr Publié le : 2026-07-23 Temps de lecture : 9 min

Font Descriptor est un objet UIFontDescriptor sous iOS et NSFontDescriptor sous macOS qui encapsule toutes les métadonnées de la police : famille, graisse, taille, interlettrage, interlignage et attributs typographiques. Au lieu de créer une police directement via UIFont(name:size:), le développeur décrit les caractéristiques souhaitées via un descripteur, et le système sélectionne la meilleure correspondance parmi les polices disponibles. Selon la Documentation Développeur Apple, UIFontDescriptor prend en charge plus de 20 attributs de police et est utilisé dans tous les frameworks typographiques iOS : de UIKit à Core Text en passant par SwiftUI.

Points clés

  • Font Descriptor — un objet descripteur contenant des métadonnées sur la famille, la graisse, la taille et les attributs typographiques
  • Permet de créer un UIFont à partir d’un ensemble d’attributs sans spécifier de nom de police concret
  • Prend en charge la modification d’une police existante : changement de taille, de graisse et de crénage sans créer de nouvel objet
  • Utilisé dans UIKit, Core Text et SwiftUI pour la recherche et la configuration des polices
  • Fournit la correspondance de polices — sélection automatique de la graisse disponible la plus proche

Qu’est-ce qu’un Font Descriptor et pourquoi en avez-vous besoin

Font Descriptor est un objet qui décrit les caractéristiques d’une police comme un ensemble de paires clé-valeur, plutôt qu’un fichier de police spécifique. Au lieu de créer une police par son nom, le développeur spécifie la famille, la graisse, la taille et les attributs optionnels, et le système sélectionne la meilleure correspondance. Cette approche est essentielle pour la typographie adaptative : le même descripteur peut fonctionner sur différentes versions d’iOS où l’ensemble des polices disponibles varie. Selon les Règles d’Interface Humaine d’iOS, la correspondance de polices via les descripteurs est la méthode recommandée pour travailler avec les polices dynamiques.

Sans Font Descriptor, les développeurs devraient vérifier la disponibilité de chaque police par son nom et définir manuellement les options de repli. Le descripteur automatise ce processus : il contient une matrice de compatibilité des graisses (normale, gras, italique, gras italique) et lorsqu’aucune correspondance exacte n’est trouvée, il retourne la plus proche disponible. La correspondance système fonctionne au niveau de Core Text et est disponible à la fois sur iOS et macOS via l’API unifiée NSFontDescriptor.

Les descripteurs sont également utilisés pour les polices personnalisées — chargées via Info.plist ou ajoutées manuellement. Si une police est enregistrée dans le système, son descripteur est créé exactement de la même manière que pour une police système. Note multiplateforme : le concept de descripteur existe également sous Android via Typeface.Builder, mais l’implémentation iOS via UIFontDescriptor fournit nettement plus d’attributs — plus de 20 contre 5 sous Android.

Propriétés et attributs principaux de Font Descriptor

UIFontDescriptor contient des attributs regroupés dans un dictionnaire fontAttributes de type [UIFontDescriptor.AttributeName: Any]. Les attributs clés incluent la famille de la police, le nom, la taille, les traits, la matrice de transformation, la taille optique et le style de texte. Selon la session 227 de la WWDC 2019 d’Apple, l’utilisation des styles de texte — Dynamic Type — est obligatoire pour les applications compatibles avec l’accessibilité.

L’attribut traits est un dictionnaire contenant des caractéristiques symboliques : le graisse (UIFontWeightTrait), l’inclinaison (UIFontSlantTrait), la largeur (UIFontWidthTrait) et autres. Ces valeurs sont utilisées par le moteur de correspondance pour sélectionner une graisse. Par exemple, UIFontWeightTrait avec une valeur de 0.0 — graisse normale, 0.3 — gras. Le système mappe automatiquement les valeurs numériques aux variantes de police disponibles.

Les attributs supplémentaires incluent featureSettings pour les fonctionnalités OpenType (ligatures, crénage, proportions numériques), visibleName pour l’affichage à l’utilisateur, matrix pour les transformations affines de la police et cascadeList pour les listes en cascade de polices de repli. La liste complète des attributs couvre pratiquement tous les scénarios typographiques sous iOS et macOS.

AttributTypeDescription
UIFontDescriptorFamilyStringFamille de la police (SF Pro, Helvetica Neue)
UIFontDescriptorNameStringNom complet de la police (HelveticaNeue-Bold)
UIFontDescriptorSizeNSNumberTaille de la police en points
UIFontDescriptorMatrixNSValueMatrice de transformation affine
UIFontDescriptorTraits[String: Any]Caractéristiques symboliques de la graisse
UIFontDescriptorTextStyleStringStyle Dynamic Type (headline, body, caption)

Créer un UIFont via Font Descriptor en Swift

La principale façon de travailler avec Font Descriptor sous iOS est de créer un descripteur puis de générer un UIFont à partir de celui-ci. C’est l’approche préférée lorsque vous avez besoin d’une police avec des caractéristiques spécifiques sans connaître le nom exact. Le processus comprend deux étapes : créer un UIFontDescriptor via un initialiseur et appeler la méthode font(withSize:) sur le descripteur.

swift
import UIKit

// Créer un descripteur de police pour la famille
let descriptor = UIFontDescriptor.init(
    fontAttributes: [
        .family: "SF Pro",
        .traits: [
            .weight: UIFont.Weight.bold
        ]
    ]
)

// Générer UIFont à partir du descripteur
let font = descriptor.font(withSize: 17)

Cette approche garantit que le système sélectionne la meilleure correspondance pour la graisse grasse de SF Pro sur l’appareil actuel. Avantage clé — le code ne dépend pas de la version d’iOS : sous iOS 13, SF Pro sera utilisé ; sous les versions antérieures, Helvetica Neue ou la police système par défaut.

Pour créer une police avec une taille dynamique, utilisez l’initialiseur avec le style de texte et l’échelle. Dynamic Type ajuste automatiquement la taille aux paramètres de l’utilisateur :

swift
// Descripteur Dynamic Type
let bodyDescriptor = UIFontDescriptor
    .preferredFontDescriptor(withTextStyle: .body)

// Mettre la police en gras
let boldDescriptor = bodyDescriptor.withSymbolicTraits([.traitBold])

// Générer UIFont en préservant la taille dynamique
let boldBodyFont = UIFont(
    descriptor: boldDescriptor!,
    size: bodyDescriptor.pointSize
)

Important : la méthode withSymbolicTraits retourne un descripteur optionnel — si la graisse demandée n’est pas disponible, elle retourne nil. Vérifiez toujours l’optionnel avant utilisation.

Modification des attributs par ajout et remplacement

Font Descriptor prend en charge un modèle immuable — chaque méthode de modification retourne un nouveau descripteur avec l’attribut modifié. Cela suit la sémantique de valeur et rend le code prévisible : le descripteur original ne change jamais. Les principales méthodes de modification sont : addingAttributes pour ajouter des attributs, withFace pour changer la graisse, withSize pour changer la taille et withMatrix pour la transformation affine.

La méthode addingAttributes est la plus flexible. Elle prend un dictionnaire d’attributs et retourne un nouveau descripteur. Lorsque les clés correspondent, les nouvelles valeurs remplacent les anciennes. Cela permet de combiner des modifications : ajouter du poids, changer la taille et activer les ligatures en un seul appel. Selon la Question Technique Apple QA1682, addingAttributes est la méthode recommandée pour les modifications en masse via une extension.

Cas d’utilisation pratique : création d’une police pour du texte à chasse fixe dans un éditeur de code. Le développeur prend le descripteur à chasse fixe du système, ajoute un poids réduit pour les lignes fines et augmente l’interlettrage via featureSettings. Cela rend le code plus lisible sans charger une police séparée.

swift
let monoDescriptor = UIFontDescriptor.monospacedDigitFontDescriptor()

// Ajouter des attributs personnalisés
let customDescriptor = monoDescriptor.addingAttributes([
    .size: 14,
    .traits: [
        .weight: UIFont.Weight.medium
    ]
])

let monoFont = UIFont(
    descriptor: customDescriptor,
    size: 14
)

Limitation : tous les attributs ne peuvent pas être modifiés après la création du descripteur. Par exemple, la famille de la police est définie une fois lors de l’initialisation. Si vous devez changer la famille, créez un nouveau descripteur. Cela est lié à l’architecture de Core Text, où le descripteur est lié à une ressource de police spécifique.

Correspondance de polices et recherche des polices système

La correspondance de polices est une fonctionnalité clé de Font Descriptor qui sélectionne automatiquement la meilleure correspondance pour les attributs demandés parmi les polices installées. Le processus comprend trois étapes : le filtrage (exclusion des polices incompatibles), le classement (tri par degré de correspondance) et la sélection (retour du meilleur résultat). La correspondance est effectuée au niveau de Core Text — le framework sous-jacent à toute la typographie iOS.

Pour trouver toutes les polices correspondant à un descripteur, utilisez la méthode matchingFontDescriptors. Elle retourne un tableau de descripteurs triés par pertinence. Le développeur peut sélectionner la correspondance exacte (premier élément) ou parcourir les options pour une logique personnalisée. Selon le Guide de Gestion des Polices Apple, c’est le seul moyen d’obtenir une liste des graisses disponibles pour une famille spécifique sans les énumérer par nom.

Cas d’utilisation : lors de la sélection d’une police dans une interface de paramétrage de texte. L’utilisateur choisit une famille, et l’application utilise matchingFontDescriptors pour obtenir toutes les graisses disponibles et les afficher dans un sélecteur. Sans correspondance, les développeurs devraient coder en dur une liste d’options qui change entre les versions d’iOS.

swift
let searchDescriptor = UIFontDescriptor.init(
    fontAttributes: [.family: "SF Mono"]
)

// Obtenir toutes les graisses disponibles
let matchingDescriptors = searchDescriptor
    .matchingFontDescriptors(withMandatoryKeys: nil)

for descriptor in matchingDescriptors {
    print(descriptor.object(forKey: .visibleName) ?? "unnamed")
}

Clés obligatoires — un paramètre qui restreint la recherche. Si vous spécifiez [.family], la correspondance retourne toutes les polices de la famille spécifiée. Si vous spécifiez [.family, .traits] — seulement celles qui correspondent à la fois à la famille et à la graisse. L’utilisation de clés obligatoires accélère la correspondance lors de la recherche d’un sous-ensemble de polices.

Performances : la correspondance est une opération synchrone qui prend de 0,5 à 5 ms sous iOS. Pour une recherche unique, c’est négligeable, mais pour une itération en masse sur des descripteurs (par exemple, dans un sélecteur avec plus de 50 polices), il est recommandé de mettre en cache les résultats. Apple recommande d’effectuer la correspondance une fois au chargement de l’écran et de sauvegarder le tableau de descripteurs.

Intégration avec Core Text et CTFontDescriptor

Core Text est un framework bas niveau en C pour travailler avec la typographie sur iOS et macOS. Son équivalent d’UIFontDescriptor est CTFontDescriptor, qui offre les mêmes capacités au niveau Core Foundation. CTFontDescriptor est utilisé dans les API Core Text pour créer des polices, mesurer du texte et rendre une typographie complexe. UIFontDescriptor est essentiellement un wrapper Objective-C autour de CTFontDescriptor avec un ensemble étendu d’attributs.

Le pont toll-free entre UIFontDescriptor et CTFontDescriptor permet de passer des descripteurs entre UIKit et Core Text sans conversion. C’est essentiel pour les applications qui utilisent un rendu de texte personnalisé — par exemple, les éditeurs de texte basés sur TextKit ou les éditeurs de code avec coloration syntaxique. Exemple : CTFontDescriptorCreateCopyWithAttribute crée une copie du descripteur avec un attribut ajouté — un analogue d’addingAttributes d’UIFontDescriptor.

L’attribut clé kCTFontURLAttribute dans CTFontDescriptor contient l’URL du fichier de police. Cela permet de déterminer si une police est système ou personnalisée. Pour les polices personnalisées, l’URL pointe vers le fichier de police (.ttf ou .otf) ; pour les polices système, vers le répertoire des polices système. Les données via le descripteur sont en lecture seule ; la modification du fichier de police via URL n’est pas prise en charge.

Pour la typographie avancée — ligatures personnalisées, substitutions contextuelles, glyphes alternatifs — utilisez CTFontDescriptorCopyAttribute avec la clé kCTFontFeatureSettingsAttribute. Cet attribut contient un tableau de dictionnaires de fonctionnalités OpenType qui peuvent être ajoutés via le descripteur. Selon le Guide de Programmation Core Text d’Apple, combiner UIFontDescriptor avec Core Text donne un contrôle total sur la typographie de l’application.

Questions fréquentes

Quelle est la différence entre Font Descriptor et UIFont ?

UIFont est une police prête à l’emploi qui rend le texte. Font Descriptor est une description de police — un ensemble d’attributs à partir duquel un UIFont peut être créé. Un seul descripteur peut produire plusieurs UIFonts de tailles différentes.

Peut-on utiliser Font Descriptor pour les polices personnalisées ?

Oui. Si la police est enregistrée dans le système (via Info.plist ou Core Graphics), son descripteur est créé par famille ou par nom exactement comme pour les polices système. La correspondance fonctionne pour toutes les polices enregistrées.

Comment obtenir le nom de la police à partir du descripteur ?

Utilisez descriptor.object(forKey: .visibleName) pour obtenir le nom affiché, ou descriptor.postscriptName pour le nom PostScript. Le nom PostScript est utilisé lors de la création d’une police via UIFont(name:size:).

Qu’est-ce qu’une liste en cascade dans Font Descriptor ?

Une liste en cascade est un tableau de descripteurs imbriqués qui servent de polices de repli. Si la police principale ne contient pas un caractère nécessaire, le système vérifie séquentiellement les polices de la liste en cascade. Elle est utilisée pour la prise en charge des emojis et des caractères CJK.

Font Descriptor fonctionne-t-il dans SwiftUI ?

Oui. SwiftUI prend en charge Font Descriptor via Font(descriptor:size:). Le wrapper SwiftUI accepte un UIFontDescriptor et crée une police SwiftUI, en préservant tous les attributs du descripteur — crénage, ligatures et graisse.

Résumé

  • Font Descriptor — un objet descripteur avec des attributs de famille, graisse, taille et fonctionnalités typographiques
  • Permet de créer UIFont à partir d’un ensemble d’attributs avec correspondance automatique des polices
  • Prend en charge la modification immuable via addingAttributes, withSize, withSymbolicTraits
  • matchingFontDescriptors retourne toutes les graisses disponibles pour la recherche et la sélection de polices
  • S’intègre avec Core Text via le pont toll-free entre UIFontDescriptor et CTFontDescriptor
  • Prend en charge Dynamic Type via les styles de texte préférés et la mise à l’échelle
  • Recommandé pour la typographie adaptative qui prend en charge toutes les versions d’iOS sans vérification de disponibilité des polices

Nous développerons une application mobile clé en main

IT Sectr crée des applications iOS et Android pour les startups et les entreprises depuis 2017. Nous vous conseillerons et vous proposerons la meilleure solution.

Discuter du projet

Lisez aussi