Dynamic Type je vestavěná funkce iOS, která automaticky mění velikost písma v aplikaci podle systémových nastavení uživatele. Uživatel nastaví preferovanou velikost textu v Nastavení → Zobrazení a jas → Velikost textu a všechny aplikace podporující Dynamic Type se přizpůsobí bez dalších zásahů. Podle Apple Human Interface Guidelines, 2024 je podpora Dynamic Type povinným požadavkem pro publikování v App Store, protože se jedná o základní prvek přístupnosti na platformě iOS.
Hlavní body
Dynamic Type je technologie iOS, která se objevila v iOS 7 a umožňuje textu v aplikaci automaticky se přizpůsobit systémovým nastavením velikosti písma. Uživatel může zvětšit nebo zmenšit písmo ve všech aplikacích najednou — bez nutnosti měnit nastavení uvnitř každé aplikace zvlášť.
Podle Apple WWDC 2023, „Make Your App Visually Accessible“ více než 40 % uživatelů iOS mění velikost písma z výchozí. U věkové skupiny 65+ tento ukazatel dosahuje 70 %. Dynamic Type je povinným požadavkem pro certifikaci přístupnosti v App Store. Nedostatek podpory je důvodem k zamítnutí aplikace při revizi.
Princip fungování: aplikace používá UIFont.preferredFont(forTextStyle:) místo UIFont(name:size:). iOS automaticky vrací písmo škálované podle aktuálního systémového nastavení. Při změně velikosti v nastavení iOS vygeneruje oznámení UIContentSizeCategory.didChangeNotification — aplikace musí přepočítat rozvržení.
Dynamic Type se objevil v iOS 7 spolu s plochým designem. V iOS 10 byla přidána podpora vlastních písem přes UIFontMetrics. iOS 11 zavedl úrovně přístupnosti (až AccessibilityXXXL). iOS 15 přidal Dynamic Type do SwiftUI s automatickou podporou. S každým vydáním Apple zpřísňuje požadavky: od iOS 17 dostávají aplikace bez podpory Dynamic Type varování při nahrávání do App Store Connect.
iOS poskytuje 8 textových stylů, každý s předdefinovanou velikostí a řezem pro standardní nastavení:
| Styl | Konstanta | Velikost (L) | Použití |
|---|---|---|---|
| Large Title | .largeTitle | 34px | Hlavní nadpis obrazovky |
| Title 1 | .title1 | 28px | Nadpis sekce |
| Title 2 | .title2 | 22px | Podnadpis |
| Title 3 | .title3 | 20px | Nadpis karty |
| Headline | .headline | 17px (bold) | Tučný pro důrazy |
| Body | .body | 17px | Hlavní text |
| Callout | .callout | 16px | Doplňkový text |
| Caption 1 | .caption1 | 12px | Popisek pod obrázkem |
| Caption 2 | .caption2 | 11px | Malý popisek |
| Footnote | .footnote | 13px | Poznámka pod čarou |
Použití správného stylu není jen otázka vzhledu. UIFont.TextStyle.body v režimu AccessibilityXXXL může dosáhnout 53px. Pokud aplikace používá pro body pevné písmo 17px, text se stane nečitelným pro uživatele, kteří písmo zvětšili.
Dynamic Type nejen škáluje — zachovává vizuální hierarchii. Large Title je vždy větší než Title 1, který je větší než Body, nezávisle na úrovni škálování. Koeficienty škálování se liší: nadpisy se škálují agresivněji než hlavní text, aby hierarchie zůstala zachována i na úrovních přístupnosti.
iOS podporuje 11 úrovní škálování textu rozdělených do dvou kategorií:
Rozdíl mezi XS a AccessibilityXXXL pro styl body je od 14px do 53px — téměř 4×. Rozvržení navržené pro 17px se při 53px zcela rozpadá: text přesahuje okraje, tlačítka se překrývají, buňky najíždějí jedna na druhou.
Zkontrolujte aktuální kategorii v kódu:
let category = UIApplication.shared.preferredContentSizeCategory
// .extraSmall, .small, .medium, .large, .extraLarge ...
if category.isAccessibilityCategory {
// Povolit alternativní rozvržení
}
Kategorie velikosti textu je dostupná přes traitCollection.uiContentSizeCategory. Při změně systémového nastavení iOS volá traitCollectionDidChange na všech UIView. V této metodě musíte aktualizovat písma a přepočítat rozvržení. SwiftUI to dělá automaticky — UIKit vyžaduje ruční odběr.
Pro UICollectionView použijte UICollectionViewCompositionalLayout — automaticky přizpůsobí počet sloupců šířce obrazovky a velikosti textu. Na úrovních přístupnosti přepněte z dvousloupcového na jednosloupcové rozložení, aby se text neořezával a prvky se nepřekrývaly. Použijte podmíněné rozložení: pro regular width — dva sloupce, pro compact nebo accessibility — jeden sloupec.
Základní implementace v UIKit — UIFont.preferredFont(forTextStyle:). Tato metoda vrací písmo škálované podle aktuálního systémového nastavení:
titleLabel.font = UIFont.preferredFont(forTextStyle: .headline)
bodyLabel.font = UIFont.preferredFont(forTextStyle: .body)
Pro vlastní písma použijte UIFontMetrics:
let customFont = UIFont(name: "Montserrat-Regular", size: 16)!
titleLabel.font = UIFontMetrics(forTextStyle: .body)
.scaledFont(for: customFont)
// Sledování změn velikosti
NotificationCenter.default.addObserver(
self,
selector: #selector(preferredContentSizeChanged),
name: UIContentSizeCategory.didChangeNotification,
object: nil
)
Pro UILabel v Interface Builder stačí nastavit písmo jako textový styl (Text Style) a zapnout „Automatically Adjusts Font“. Pro vlastní písma IB nepodporuje UIFontMetrics — pouze přes kód.
UIFontMetrics používá stejnou scaling curve jako preferredFont. Můžete nastavit fromTextStyle: .body, .headline atd. Každý styl má svůj vlastní koeficient škálování. Body se škáluje mírně, Large Title agresivně. Pokud je vaše vlastní písmo použito pro hlavní text, použijte .body.
Ve SwiftUI je podpora Dynamic Type integrována ve výchozím nastavení. Všechny systémové modifikátory (.font(.body), .font(.title)) se automaticky škálují. Vývojář nemusí volat UIFont.preferredFont.
Příklad:
Text("Hlavní text")
.font(.body)
.lineLimit(nil)
.minimumScaleFactor(0.5)
Pro vlastní měřítka použijte DynamicTypeSize:
@Environment(\.dynamicTypeSize) var dynamicTypeSize
var body: some View {
Text("Adaptivní text")
.font(.body)
.padding(dynamicTypeSize <= .large ? 8 : 16)
}
SwiftUI automaticky aktualizuje zobrazení při změně systémové velikosti textu — bez dalších odběrů oznámení.
Modifikátor .font(.body) funguje pouze pro systémové písmo. Pro vlastní písma ve SwiftUI použijte Font.custom s UIFontMetrics na pozadí. Od iOS 16 SwiftUI podporuje DynamicTypeSize v @Environment, což umožňuje přizpůsobit odsazení a rozvržení.
Auto Layout je povinnou podmínkou pro podporu Dynamic Type. Pevné šířky a výšky (>=, <=) se na úrovních přístupnosti rozpadají. Použijte intrinsicContentSize pro UILabel — automaticky vypočítá výšku podle aktuální velikosti písma.
Pravidla adaptivního rozvržení:
Pro dlouhé texty (např. články, podmínky použití) nastavte minimumScaleFactor na UILabel — zmenšuje text jako poslední možnost, když Auto Layout nemůže pojmout obsah. Hodnota 0.5 znamená, že písmo se může zmenšit až na 50 % preferované velikosti.
Příklad přizpůsobení okrajů podle kategorie velikosti:
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)
Ořezávání textu — UILabel s numberOfLines = 1 a pevnou šířkou ořezává text na AccessibilityXL. Řešení: numberOfLines = 0 a trailing constraint. Překrývání prvků — tlačítka s pevnou výškou se překrývají. Řešení: UIStackView s automatic spacing. Přesahování mimo obrazovku — ScrollView je povinné pro úrovně přístupnosti.
Simulátor Xcode umožňuje změnit velikost textu: v nabídce simulátoru Settings → Accessibility → Display & Text Size → Larger Text. Přepínejte mezi všemi 11 úrovněmi a kontrolujte, že se text neořezává, tlačítka jsou dostupná a rozvržení se nerozpadá.
Pro automatizované testování použijte nastavení contentSizeCategory v XCUIApplication:
func testAccessibilitySizes() {
let app = XCUIApplication()
app.launchArguments += [
"-UIPreferredContentSizeCategoryName",
"UICTContentSizeCategoryAccessibilityXXXL"
]
app.launch()
app.scrollViews.buttons["Odeslat"].tap()
XCTAssertTrue(app.staticTexts["Formulář byl odeslán"]
.waitForExistence(timeout: 5))
}
XCUITest s různými launchArguments umožňuje otestovat všechny úrovně škálování v CI. Nezapomeňte zkontrolovat kategorie přístupnosti zvlášť — nejčastěji rozbíjejí rozvržení. Podle Apple se 70 % chyb Dynamic Type objevuje právě na úrovních přístupnosti, protože vývojáři testují pouze standardní velikosti.
Xcode Accessibility Inspector ukazuje, jaká písma vybraný prvek používá — pevné nebo škálovatelné. Pokud prvek nereaguje na změnu velikosti textu v simulátoru, znamená to, že se používá pevné písmo. Nahraďte jej UIFont.preferredFont nebo UIFontMetrics.
Často kladené otázky
Je to automatické škálování textu v aplikaci podle systémových nastavení velikosti. Uživatel změní velikost v Nastavení — všechny podporující aplikace se přizpůsobí bez zásahu vývojáře.
Ne. Pro vlastní písma použijte UIFontMetrics(scaledFont:). Metoda škáluje libovolné písmo relativně k zadanému textovému stylu při zachování proporcí.
11 úrovní: 5 standardních (XS, S, M, L, XL) a 6 úrovní přístupnosti (od AccessibilityXL do AccessibilityXXXXXL). Velikost písma body se může pohybovat od 14px do 53px.
V UIKit přes UIContentSizeCategory.didChangeNotification. Ve SwiftUI použijte @Environment(\.dynamicTypeSize) — zobrazení se automaticky aktualizuje při změně systémového nastavení.
Uživatelé se zvětšeným písmem uvidí ořezaný text, překrývající se prvky a nefunkční tlačítka. Aplikace může být zamítnuta v App Store Review za porušení požadavků na přístupnost.
Shrnutí
Vyvineme mobilní aplikaci na klíč
IT Sectr vytváří aplikace pro iOS a Android pro startupy a podniky od roku 2017. Poradíme vám a navrhneme nejlepší řešení.
Přečtěte si také