Dynamic Type : concepts clés, styles de texte et fonctionnement sous iOS

Auteur : IT Sectr Publié le : 2026-05-16 Temps de lecture : 9 min

Dynamic Type est une fonction intégrée d’iOS qui modifie automatiquement la taille de la police dans une application en fonction des réglages système de l’utilisateur. L’utilisateur définit sa taille de texte préférée dans Réglages → Écran et luminosité → Taille du texte, et toutes les applications prenant en charge Dynamic Type s’adaptent sans action supplémentaire. Selon les Apple Human Interface Guidelines, 2024, la prise en charge de Dynamic Type est une exigence obligatoire pour la publication sur l’App Store, car il s’agit d’un élément de base de l’accessibilité sur la plateforme iOS.

Points clés

  • Dynamic Type — un mécanisme iOS pour mettre à l’échelle le texte automatiquement selon les réglages de taille de police du système
  • La prise en charge est assurée via les styles de texte (UIFont.TextStyle) — body, headline, caption, title et autres
  • Le système prend en charge 11 niveaux de mise à l’échelle, de XSmall à AccessibilityXXXL
  • Pour les polices personnalisées, on utilise la méthode UIFontMetrics, qui met à l’échelle toute police par rapport au style body
  • La mise en page doit être adaptative — UIStackView, Auto Layout et hauteurs dynamiques des cellules sont obligatoires

Qu’est-ce que Dynamic Type sous iOS

Dynamic Type est une technologie iOS introduite dans iOS 7 qui permet au texte d’une application de s’ajuster automatiquement aux réglages de taille de police du système. L’utilisateur peut augmenter ou diminuer la police dans toutes les applications à la fois — sans avoir à modifier les réglages dans chaque application individuellement.

Selon la Apple WWDC 2023, « Make Your App Visually Accessible », plus de 40 % des utilisateurs iOS modifient la taille de la police par rapport au réglage par défaut. Pour la tranche d’âge 65+ ans, ce chiffre atteint 70 %. Dynamic Type est une exigence obligatoire pour la certification d’accessibilité de l’App Store. L’absence de prise en charge est un motif de rejet lors de la révision.

Principe de fonctionnement : l’application utilise UIFont.preferredFont(forTextStyle:) au lieu de UIFont(name :size :). iOS retourne automatiquement une police dimensionnée selon le réglage système actuel. Lorsque la taille change dans les réglages, iOS génère une notification UIContentSizeCategory.didChangeNotification — l’application doit recalculer la mise en page.

Historique de Dynamic Type

Dynamic Type est apparu dans iOS 7 avec le design plat. iOS 10 a ajouté la prise en charge des polices personnalisées via UIFontMetrics. iOS 11 a introduit les niveaux d’accessibilité (jusqu’à AccessibilityXXXL). iOS 15 a ajouté Dynamic Type dans SwiftUI avec une prise en charge automatique. À chaque version, Apple renforce les exigences : à partir d’iOS 17, les applications sans prise en charge de Dynamic Type reçoivent un avertissement lors du téléchargement dans App Store Connect.

Styles de texte UIFont.TextStyle

iOS propose 8 styles de texte, chacun avec une taille et un graisse prédéfinis pour le réglage par défaut :

StyleConstanteTaille (L)Usage
Large Title.largeTitle34pxTitre principal de l’écran
Title 1.title128pxTitre de section
Title 2.title222pxSous-titre
Title 3.title320pxTitre de carte
Headline.headline17px (gras)Gras pour emphase
Body.body17pxTexte principal
Callout.callout16pxTexte complémentaire
Caption 1.caption112pxLégende d’image
Caption 2.caption211pxPetite légende
Footnote.footnote13pxNote de bas de page

Utiliser le bon style n’est pas simplement une question d’« apparence ». UIFont.TextStyle.body en mode AccessibilityXXXL peut atteindre 53 px. Si une application utilise une police fixe de 17 px pour le body, le texte devient illisible pour les utilisateurs qui ont augmenté la taille de la police.

Hiérarchie visuelle via les styles

Dynamic Type ne se contente pas de mettre à l’échelle — il préserve la hiérarchie visuelle. Large Title est toujours plus grand que Title 1, qui est plus grand que Body, quel que soit le niveau de mise à l’échelle. Les coefficients de mise à l’échelle diffèrent : les titres sont mis à l’échelle de manière plus agressive que le texte principal, afin que la hiérarchie soit maintenue même aux niveaux d’accessibilité.

Niveaux de mise à l’échelle

iOS prend en charge 11 niveaux de mise à l’échelle du texte, répartis en deux catégories :

  • Tailles standard (5 niveaux) : XS, S, M, L (par défaut), XL
  • Tailles d’accessibilité (6 niveaux) : accessibilityXL, accessibilityXXL, accessibilityXXXL, accessibilityXXXXL, accessibilityXXXXXL, accessibilityXXXXXXL

La différence entre XS et AccessibilityXXXL pour le style body varie de 14 px à 53 px — presque 4×. Une mise en page conçue pour 17 px se brise complètement à 53 px : le texte déborde, les boutons se chevauchent, les cellules entrent en collision.

Vérifier la catégorie actuelle dans le code :

swift
let category = UIApplication.shared.preferredContentSizeCategory
// .extraSmall, .small, .medium, .large, .extraLarge ...
if category.isAccessibilityCategory {
    // Activer la mise en page alternative
}

traitCollection et taille du texte

La catégorie de taille de texte est disponible via traitCollection.uiContentSizeCategory. Lorsque le réglage système change, iOS appelle traitCollectionDidChange sur toutes les UIView. Dans cette méthode, vous devez mettre à jour les polices et recalculer la mise en page. SwiftUI le fait automatiquement — UIKit nécessite un abonnement manuel.

Pour UICollectionView, utilisez UICollectionViewCompositionalLayout — il ajuste automatiquement le nombre de colonnes à la largeur de l’écran et à la taille du texte. Aux niveaux d’accessibilité, passez d’une mise en page à deux colonnes à une colonne unique pour que le texte ne soit pas tronqué et que les éléments ne se chevauchent pas. Utilisez une mise en page conditionnelle : pour une largeur régulière — deux colonnes, pour compact ou accessibilité — une colonne.

Implémentation dans UIKit

L’implémentation de base dans UIKit — UIFont.preferredFont(forTextStyle:). Cette méthode retourne une police dimensionnée selon le réglage système actuel :

swift
titleLabel.font = UIFont.preferredFont(forTextStyle: .headline)
bodyLabel.font = UIFont.preferredFont(forTextStyle: .body)

Pour les polices personnalisées, utilisez UIFontMetrics :

swift
let customFont = UIFont(name: "Montserrat-Regular", size: 16)!
titleLabel.font = UIFontMetrics(forTextStyle: .body)
    .scaledFont(for: customFont)

// Suivi des changements de taille
NotificationCenter.default.addObserver(
    self,
    selector: #selector(preferredContentSizeChanged),
    name: UIContentSizeCategory.didChangeNotification,
    object: nil
)

Pour UILabel dans Interface Builder, il suffit de définir la police comme un style de texte et d’activer « Automatically Adjusts Font ». Pour les polices personnalisées, Interface Builder ne prend pas en charge UIFontMetrics — uniquement via le code.

UIFontMetrics et courbe de mise à l’échelle

UIFontMetrics utilise la même courbe de mise à l’échelle que preferredFont. Vous pouvez spécifier fromTextStyle : .body, .headline, etc. Chaque style a son propre coefficient de mise à l’échelle. Body est mis à l’échelle modérément, Large Title de manière agressive. Si votre police personnalisée est utilisée pour le texte principal, utilisez .body.

Dynamic Type dans SwiftUI

Dans SwiftUI, la prise en charge de Dynamic Type est intégrée par défaut. Tous les modificateurs système (.font(.body), .font(.title)) se mettent automatiquement à l’échelle. Le développeur n’a pas besoin d’appeler UIFont.preferredFont.

Exemple :

swift
Text("Texte principal")
    .font(.body)
    .lineLimit(nil)
    .minimumScaleFactor(0.5)

Pour les échelles personnalisées, utilisez DynamicTypeSize :

swift
@Environment(\.dynamicTypeSize) var dynamicTypeSize

var body: some View {
    Text("Texte adaptatif")
        .font(.body)
        .padding(dynamicTypeSize <= .large ? 8 : 16)
}

SwiftUI met automatiquement à jour la vue lorsque la taille du texte système change — aucun abonnement supplémentaire aux notifications n’est nécessaire.

Limitation de Dynamic Type dans SwiftUI

Le modificateur .font(.body) ne fonctionne qu’avec la police système. Pour les polices personnalisées dans SwiftUI, utilisez Font.custom avec UIFontMetrics en interne. À partir d’iOS 16, SwiftUI prend en charge DynamicTypeSize dans @Environment, ce qui permet d’adapter le padding et la mise en page.

Adaptation de la mise en page pour les grandes polices

Auto Layout est un prérequis pour la prise en charge de Dynamic Type. Les largeurs et hauteurs fixes (>=, <=) se brisent aux tailles d’accessibilité. Utilisez intrinsicContentSize pour UILabel — il calcule automatiquement la hauteur pour la taille de police actuelle.

Règles de mise en page adaptative :

  • UIStackView avec distribution = fill et spacing >= 8 — les éléments passeront à la ligne suivante
  • UITableViewCell avec automaticDimension — la hauteur de la cellule s’adapte au contenu
  • numberOfLines = 0 sur UILabel — le texte n’est pas tronqué mais renvoyé à la ligne
  • Boutons avec edgeInsets — ajoutez du padding aux niveaux d’accessibilité via traitCollection.preferredContentSizeCategory

Pour les textes longs (par exemple, articles, conditions d’utilisation), définissez minimumScaleFactor sur UILabel — cela réduit le texte en dernier recours lorsque Auto Layout ne peut pas contenir le contenu. Une valeur de 0.5 signifie que la police peut se réduire à 50 % de la taille préférée.

Exemple d’adaptation du padding selon la catégorie de taille :

swift
let isAccessibility = traitCollection
    .preferredContentSizeCategory.isAccessibilityCategory
stackView.spacing = isAccessibility ? 16 : 8
button.contentEdgeInsets = isAccessibility
    ? UIEdgeInsets(top: 16, left: 24, bottom: 16, right: 24)
    : UIEdgeInsets(top: 8, left: 16, bottom: 8, right: 16)

Problèmes typiques de mise en page aux niveaux d’accessibilité

Troncature du texte — UILabel avec numberOfLines = 1 et largeur fixe tronque le texte à AccessibilityXL. Solution : numberOfLines = 0 et contrainte trailing. Chevauchement des éléments — les boutons à hauteur fixe se chevauchent. Solution : UIStackView avec espacement automatique. Contenu hors écran — ScrollView est obligatoire pour les niveaux d’accessibilité.

Test de Dynamic Type

Le Simulateur Xcode permet de modifier la taille du texte : dans le menu du simulateur, allez dans Settings → Accessibility → Display & Text Size → Larger Text. Basculez entre les 11 niveaux et vérifiez que le texte n’est pas tronqué, les boutons sont accessibles et la mise en page ne se brise pas.

Pour les tests automatisés, utilisez le paramètre contentSizeCategory dans XCUIApplication :

swift
func testAccessibilitySizes() {
    let app = XCUIApplication()
    app.launchArguments += [
        "-UIPreferredContentSizeCategoryName",
        "UICTContentSizeCategoryAccessibilityXXXL"
    ]
    app.launch()
    app.scrollViews.buttons["Envoyer"].tap()
    XCTAssertTrue(app.staticTexts["Formulaire envoyé"]
        .waitForExistence(timeout: 5))
}

XCUITest avec différents launchArguments permet de vérifier tous les niveaux de mise à l’échelle en CI. N’oubliez pas de tester les catégories d’accessibilité séparément — ce sont celles qui brisent le plus souvent la mise en page. Selon Apple, 70 % des bugs de Dynamic Type sont découverts spécifiquement aux niveaux d’accessibilité, car les développeurs ne testent que les tailles standard.

Accessibility Inspector : vérification de Dynamic Type

Xcode Accessibility Inspector montre quelles polices l’élément sélectionné utilise — fixes ou redimensionnables. Si l’élément ne répond pas aux changements de taille de texte dans le simulateur, une police fixe est utilisée. Remplacez-la par UIFont.preferredFont ou UIFontMetrics.

Foire aux questions

Qu’est-ce que Dynamic Type sous iOS en termes simples ?

C’est la mise à l’échelle automatique du texte dans une application selon les réglages de taille du système. L’utilisateur modifie la taille dans les Réglages — toutes les applications compatibles s’adaptent sans intervention du développeur.

Dynamic Type fonctionne-t-il uniquement avec les polices système ?

Non. Pour les polices personnalisées, utilisez UIFontMetrics(scaledFont :). Cette méthode met à l’échelle toute police par rapport au style de texte spécifié, en conservant les proportions.

Combien de niveaux de mise à l’échelle iOS prend-il en charge ?

11 niveaux : 5 standards (XS, S, M, L, XL) et 6 niveaux d’accessibilité (d’AccessibilityXL à AccessibilityXXXXXL). La taille de la police body peut varier de 14 px à 53 px.

Comment s’abonner aux changements de taille du texte ?

Dans UIKit via UIContentSizeCategory.didChangeNotification. Dans SwiftUI, utilisez @Environment(\.dynamicTypeSize) — la vue est mise à jour automatiquement lorsque le réglage système change.

Que se passe-t-il si Dynamic Type n’est pas pris en charge ?

Les utilisateurs avec une police agrandie verront du texte tronqué, des éléments qui se chevauchent et des boutons défaillants. L’application peut être rejetée lors de la révision de l’App Store pour violation des exigences d’accessibilité.

Résumé

  • Dynamic Type — mécanisme intégré d’iOS pour mettre à l’échelle le texte selon les réglages système ; obligatoire pour l’App Store
  • Utilisez UIFont.preferredFont(forTextStyle:) pour les polices système et UIFontMetrics pour les personnalisées
  • iOS prend en charge 11 niveaux de mise à l’échelle — de XS à AccessibilityXXXXXL (14–53 px pour body)
  • Dans SwiftUI, Dynamic Type fonctionne automatiquement via .font(.body) et @Environment(\.dynamicTypeSize)
  • La mise en page doit être adaptative : UIStackView, automaticDimension dans les tableaux, numberOfLines = 0
  • Testez les 11 niveaux, en particulier les catégories d’accessibilité — 70 % des mises en page s’y brisent
  • L’abonnement à UIContentSizeCategory.didChangeNotification est obligatoire pour les applications UIKit

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