Principalele puncte
Dynamic Type — tehnologia Apple care permite fonturilor aplicației să se scaleze automat la modificarea dimensiunii sistemului de text. Utilizatorul setează dimensiunea preferată în Settings → Accessibility → Display & Text Size, iar toate aplicațiile care suportă Dynamic Type adaptează corpul de literă fără repornire.
Sistemul oferă 11 trepte de scalare: de la XS (14pt de bază) la XXXL (23pt de bază), precum și 5 dimensiuni suplimentare de accesibilitate (AX1–AX5) pentru utilizatorii cu deficiențe de vedere severe. La modificarea dimensiunii, iOS generează notificarea UIContentSizeCategory.didChangeNotification, iar aplicația trebuie să recitească fonturile prin UIFontMetrics. Conform Apple Human Interface Guidelines, Dynamic Type nu modifică intervalul dintre rânduri și proporțiile literelor — doar corpul de literă, ceea ce păstrează lizibilitatea la toate dimensiunile.
Dynamic Type este obligatoriu pentru aplicațiile care aspiră la statutul de accesibile (accessibility). La WWDC 2024, Apple a anunțat că aplicațiile fără suport pentru tipul dinamic riscă să fie respinse la review, dacă funcționalitatea lor principală este legată de citirea textului. În proiectele IT Sectr, implementăm Dynamic Type de la prima versiune — economisește până la 20% din timpul pentru adaptarea ulterioară la accesibilitate.
Apple oferă 11 stiluri de text predefinite, fiecare afișat în UIFontDescriptor.UIAttributes pentru fontul de sistem SF Pro. Dezvoltatorul nu setează dimensiunea în pixeli — alege un stil semantic, iar iOS aplică corpul de literă corespunzător în funcție de setările utilizatorului.
| Stil | Dimensiune (implicit) | Dimensiune (AX5) | Destinație |
|---|---|---|---|
| .largeTitle | 34pt | 62pt | Titluri de ecran de prim nivel |
| .title1 | 28pt | 50pt | Titluri secundare |
| .title2 | 22pt | 40pt | Titluri de secțiuni |
| .title3 | 20pt | 36pt | Subtitluri |
| .headline | 17pt semibold | 31pt | Text evidențiat în liste |
| .body | 17pt | 31pt | Text principal |
| .callout | 16pt | 29pt | Note și text suplimentar |
| .subheadline | 15pt | 27pt | Descrieri ale elementelor |
| .footnote | 13pt | 23pt | Note de subsol și text mic |
| .caption1 | 12pt | 21pt | Descrieri ale imaginilor |
| .caption2 | 11pt | 19pt | Etichete și descrieri mici |
Fiecare stil folosește fontul de sistem SF Pro cu o grosime fixă (Regular pentru body, Bold pentru headline). Fonturile personalizate se conectează prin UIFontMetrics — singura modalitate corectă de a adapta un font terț la tipul dinamic.
UIFontMetrics — clasa introdusă în iOS 11, care scalează orice UIFont proporțional cu stilul de text ales. Înainte de iOS 11, dezvoltatorii foloseau apelul direct preferredFontForTextStyle, care returnează doar fontul de sistem SF Pro. UIFontMetrics rezolvă această problemă: acceptă orice font și returnează versiunea sa scalată, păstrând grosimea și proporțiile.
Metoda scaledFont(for:) calculează factorul de scalare pe baza dimensiunii curente a textului utilizatorului: dacă este selectată dimensiunea „Mare" (Large), factorul este 1.0; dacă „Foarte mare" (AX1) — aproximativ 1.3; pentru „Maxim" (AX5) — până la 1.8. Factorul se aplică la dimensiunea de bază a fontului personalizat, nu la cel de sistem — aceasta garantează că intenția designerului se păstrează la toate dimensiunile.
UIFontMetrics este recomandat pentru toate fonturile personalizate din aplicație. La WWDC 2024, Apple a arătat instrumentul Accessibility Inspector, care verifică suportul Dynamic Type și evidențiază elementele care folosesc un corp de literă fix în loc de UIFontMetrics. În IT Sectr, am implementat UIFontMetrics în toate proiectele din 2018 — aceasta a redus numărul de erori de suprapunere a textului cu 35%.
Cea mai simplă modalitate de a obține un font dinamic pentru o etichetă. Codul arată cum să setați un UILabel cu stilul .body, care reacționează automat la modificarea dimensiunii sistemului de text.
import UIKit
class GreetingViewController: UIViewController {
private let label: UILabel = {
let l = UILabel()
l.text = "Hello, Dynamic Type!"
l.font = UIFont.preferredFont(forTextStyle: .body)
l.adjustsFontForContentSizeCategory = true
l.translatesAutoresizingMaskIntoConstraints = false
return l
}()
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(label)
NSLayoutConstraint.activate([
label.centerXAnchor.constraint(equalTo: view.centerXAnchor),
label.centerYAnchor.constraint(equalTo: view.centerYAnchor),
])
}
}
Indicatorul adjustsFontForContentSizeCategory = true actualizează automat fontul la modificarea dimensiunii sistemului de text — fără acest indicator, Dynamic Type nu va funcționa pentru eticheta existentă. La modificarea dimensiunii, iOS apelează layoutIfNeeded, iar label actualizează fontul fără intervenție manuală.
La utilizarea unui font personalizat (de exemplu, Montserrat), apelul preferredFontForTextStyle va returna SF Pro, nu fontul dumneavoastră. UIFontMetrics scalează exact fontul personalizat, păstrându-i designul.
import UIKit
extension UIFont {
static func customDynamicFont(name: String,
size: CGFloat,
style: UIFont.TextStyle) -> UIFont {
guard let baseFont = UIFont(name: name, size: size) else {
return .preferredFont(forTextStyle: style)
}
return UIFontMetrics(forTextStyle: style).scaledFont(for: baseFont)
}
}
let titleFont = UIFont.customDynamicFont(
name: "Montserrat-Bold",
size: 20,
style: .title3
)
Metoda scaledFont(for:) acceptă un UIFont de bază și returnează o versiune scalată proporțional cu stilul .title3. La dimensiunea de accesibilitate AX5, fontul Montserrat-Bold 20pt se transformă în ~36pt — exact cât s-ar mări fontul de sistem al acestui stil. În IT Sectr, folosim acest model în toate proiectele cu fonturi personalizate din 2018, ceea ce a eliminat complet plângerile privind textul mic de la utilizatorii cu deficiențe de vedere.
Dacă actualizați fontul manual (fără adjustsFontForContentSizeCategory), abonați-vă la notificarea UIContentSizeCategory.didChangeNotification. Acest lucru este necesar pentru elementele UI personalizate care nu moștenesc actualizarea automată a fontului.
import UIKit
class DynamicLabel: UILabel {
private var customFont: UIFont?
private var textStyle: UIFont.TextStyle = .body
func configure(font: UIFont, style: UIFont.TextStyle) {
customFont = font
textStyle = style
NotificationCenter.default.addObserver(
self,
selector: #selector(updateFont),
name: UIContentSizeCategory.didChangeNotification,
object: nil
)
updateFont()
}
@objc private func updateFont() {
guard let base = customFont else { return }
self.font = UIFontMetrics(forTextStyle: textStyle).scaledFont(for: base)
}
deinit {
NotificationCenter.default.removeObserver(self)
}
}
Abonarea la didChangeNotification garantează că elementul personalizat va actualiza fontul la orice modificare a setărilor sistemului fără repornirea aplicației. Începând cu iOS 15, notificarea sosește chiar și la modificarea dimensiunii textului prin Control Center în aplicațiile care suportă Live Text Size.
Întrebări frecvente
Dynamic Type este disponibil pe iOS 7 și mai nou. UIFontMetrics a apărut în iOS 11 — înainte de acesta se folosea direct metoda preferredFontForTextStyle. Pe iOS 15+, tipul dinamic suportă dimensiuni suplimentare de accesibilitate (AX1–AX5) pentru fonturi mari. Aplicațiile care suportă iOS 10 și mai vechi folosesc preferredFontForTextStyle fără UIFontMetrics, ceea ce limitează suportul doar la fontul de sistem SF Pro.
În Xcode 15+, deschideți simulatorul și selectați Settings → Accessibility → Display & Text Size → Larger Text. Trageți glisorul pentru a modifica dimensiunea. În Xcode există Debug → Accessibility Inspector, care evidențiază elementele cu font fix. Pentru automatizare, folosiți un test care modifică UISlider setărilor prin XCUITest — aceasta garantează că toate ecranele se reconstruiesc corect.
Da, Auto Layout cu tip dinamic necesită utilizarea intrinsicContentSize în UILabel și UIButton. La dimensiunile de accesibilitate, textul poate ieși din limitele superview — adăugați UIScrollView sau măriți constrângerile leading/trailing. Folosiți UIFontMetrics.scaledValue pentru margini (padding), astfel încât și spațiile dintre litere să se scaleze proporțional cu fontul.
Concluzii
Vom dezvolta o aplicație mobilă la cheie
IT Sectr creează aplicații iOS și Android pentru startup-uri și afaceri din 2017. Vă vom consilia și vă vom propune cea mai bună soluție.
Citiți și