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 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.
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.
iOS propose 8 styles de texte, chacun avec une taille et un graisse prédéfinis pour le réglage par défaut :
| Style | Constante | Taille (L) | Usage |
|---|---|---|---|
| Large Title | .largeTitle | 34px | Titre principal de l’écran |
| Title 1 | .title1 | 28px | Titre de section |
| Title 2 | .title2 | 22px | Sous-titre |
| Title 3 | .title3 | 20px | Titre de carte |
| Headline | .headline | 17px (gras) | Gras pour emphase |
| Body | .body | 17px | Texte principal |
| Callout | .callout | 16px | Texte complémentaire |
| Caption 1 | .caption1 | 12px | Légende d’image |
| Caption 2 | .caption2 | 11px | Petite légende |
| Footnote | .footnote | 13px | Note 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.
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é.
iOS prend en charge 11 niveaux de mise à l’échelle du texte, répartis en deux catégories :
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 :
let category = UIApplication.shared.preferredContentSizeCategory
// .extraSmall, .small, .medium, .large, .extraLarge ...
if category.isAccessibilityCategory {
// Activer la mise en page alternative
}
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.
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 :
titleLabel.font = UIFont.preferredFont(forTextStyle: .headline)
bodyLabel.font = UIFont.preferredFont(forTextStyle: .body)
Pour les polices personnalisées, utilisez UIFontMetrics :
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 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.
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 :
Text("Texte principal")
.font(.body)
.lineLimit(nil)
.minimumScaleFactor(0.5)
Pour les échelles personnalisées, utilisez DynamicTypeSize :
@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.
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.
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 :
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 :
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)
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é.
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 :
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.
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
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.
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.
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.
Dans UIKit via UIContentSizeCategory.didChangeNotification. Dans SwiftUI, utilisez @Environment(\.dynamicTypeSize) — la vue est mise à jour automatiquement lorsque le réglage système change.
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é
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.