Κύρια σημεία
Dynamic Type — τεχνολογία της Apple που επιτρέπει στις γραμματοσειρές της εφαρμογής να κλιμακώνονται αυτόματα όταν αλλάζει το μέγεθος κειμένου συστήματος. Ο χρήστης ορίζει το προτιμώμενο μέγεθος στο Settings → Accessibility → Display & Text Size, και όλες οι εφαρμογές που υποστηρίζουν Dynamic Type προσαρμόζουν το μέγεθος γραμμάτων χωρίς επανεκκίνηση.
Το σύστημα προσφέρει 11 επίπεδα κλιμάκωσης: από XS (14pt βασικό) έως XXXL (23pt βασικό), καθώς και 5 επιπλέον μεγέθη προσβασιμότητας (AX1–AX5) για χρήστες με σοβαρές προβλήματα όρασης. Κατά την αλλαγή μεγέθους, το iOS δημιουργεί την ειδοποίηση UIContentSizeCategory.didChangeNotification και η εφαρμογή πρέπει να ξαναδιαβάσει τις γραμματοσειρές μέσω του UIFontMetrics. Σύμφωνα με το Apple Human Interface Guidelines, το Dynamic Type δεν αλλάζει το διάστιχο και τις αναλογίες γραμμάτων — μόνο το μέγεθος γραμμάτων, διατηρώντας την αναγνωσιμότητα σε όλα τα μεγέθη.
Το Dynamic Type είναι υποχρεωτικό για εφαρμογές που επιδιώκουν την κατάσταση προσβασιμότητας (accessibility). Στο WWDC 2024, η Apple ανακοίνωσε ότι εφαρμογές χωρίς υποστήριξη δυναμικού τύπου κινδυνεύουν με απόρριψη κατά τον έλεγχο, εάν η κύρια λειτουργικότητά τους σχετίζεται με ανάγνωση κειμένου. Στα έργα της IT Sectr, εφαρμόζουμε το Dynamic Type από την πρώτη έκδοση — αυτό εξοικονομεί έως και 20% χρόνου για μεταγενέστερη προσαρμογή προσβασιμότητας.
Η Apple παρέχει 11 προκαθορισμένα στυλ κειμένου, το καθένα από τα οποία εμφανίζεται στο UIFontDescriptor.UIAttributes για τη γραμματοσειρά συστήματος SF Pro. Ο προγραμματιστής δεν ορίζει μέγεθος σε pixel — επιλέγει ένα σημασιολογικό στυλ και το iOS εφαρμόζει το κατάλληλο μέγεθος γραμμάτων ανάλογα με τις ρυθμίσεις του χρήστη.
| Στυλ | Μέγεθος (προεπιλογή) | Μέγεθος (AX5) | Χρήση |
|---|---|---|---|
| .largeTitle | 34pt | 62pt | Τίτλοι οθόνης πρώτου επιπέδου |
| .title1 | 28pt | 50pt | Δευτερεύοντες τίτλοι |
| .title2 | 22pt | 40pt | Τίτλοι ενοτήτων |
| .title3 | 20pt | 36pt | Υπότιτλοι |
| .headline | 17pt semibold | 31pt | Έντονο κείμενο σε λίστες |
| .body | 17pt | 31pt | Κύριο κείμενο |
| .callout | 16pt | 29pt | Παραπομπές και πρόσθετο κείμενο |
| .subheadline | 15pt | 27pt | Περιγραφές στοιχείων |
| .footnote | 13pt | 23pt | Υποσημειώσεις και μικρό κείμενο |
| .caption1 | 12pt | 21pt | Περιγραφές εικόνων |
| .caption2 | 11pt | 19pt | Ετικέτες και μικρές περιγραφές |
Κάθε στυλ χρησιμοποιεί τη γραμματοσειρά συστήματος SF Pro με σταθερή μορφή (Regular για body, Bold για headline). Οι προσαρμοσμένες γραμματοσειρές συνδέονται μέσω του UIFontMetrics — ο μόνος σωστός τρόπος προσαρμογής γραμματοσειράς τρίτου μέρους σε δυναμικό τύπο.
UIFontMetrics — κλάση που εισήχθη στο iOS 11, η οποία κλιμακώνει οποιοδήποτε UIFont αναλογικά προς το επιλεγμένο στυλ κειμένου. Πριν από το iOS 11, οι προγραμματιστές χρησιμοποιούσαν άμεση κλήση του preferredFontForTextStyle, η οποία επιστρέφει μόνο τη γραμματοσειρά συστήματος SF Pro. Το UIFontMetrics λύνει αυτό το πρόβλημα: δέχεται οποιαδήποτε γραμματοσειρά και επιστρέφει την κλιμακωμένη έκδοσή της, διατηρώντας τη μορφή και τις αναλογίες.
Η μέθοδος scaledFont(for:) υπολογίζει τον συντελεστή κλιμάκωσης βάσει του τρέχοντος μεγέθους κειμένου του χρήστη: εάν έχει επιλεγεί μέγεθος "Μεγάλο" (Large), ο συντελεστής είναι 1.0· εάν "Πολύ μεγάλο" (AX1) — περίπου 1.3· για "Μέγιστο" (AX5) — έως 1.8. Ο συντελεστής εφαρμόζεται στο βασικό μέγεθος της προσαρμοσμένης γραμματοσειράς, όχι στη γραμματοσειρά συστήματος — αυτό εγγυάται ότι η σχεδιαστική πρόθεση διατηρείται σε όλα τα μεγέθη.
Το UIFontMetrics συνιστάται για όλες τις προσαρμοσμένες γραμματοσειρές στην εφαρμογή. Στο WWDC 2024, η Apple παρουσίασε το εργαλείο Accessibility Inspector, το οποίο ελέγχει την υποστήριξη Dynamic Type και επισημαίνει στοιχεία που χρησιμοποιούν σταθερό μέγεθος αντί για UIFontMetrics. Στην IT Sectr, εφαρμόσαμε το UIFontMetrics σε όλα τα έργα από το 2018 — αυτό μείωσε τον αριθμό σφαλμάτων με επικαλυπτόμενο κείμενο κατά 35%.
Ο απλούστερος τρόπος για να λάβετε μια δυναμική γραμματοσειρά για μια ετικέτα. Ο κώδικας δείχνει πώς να ρυθμίσετε ένα UILabel με στυλ .body, το οποίο αντιδρά αυτόματα στην αλλαγή του μεγέθους κειμένου συστήματος.
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),
])
}
}
Η σημαία adjustsFontForContentSizeCategory = true ενημερώνει αυτόματα τη γραμματοσειρά κατά την αλλαγή του μεγέθους κειμένου συστήματος — χωρίς αυτή τη σημαία, το Dynamic Type δεν θα λειτουργήσει για την υπάρχουσα ετικέτα. Κατά την αλλαγή μεγέθους, το iOS καλεί το layoutIfNeeded και η ετικέτα ενημερώνει τη γραμματοσειρά χωρίς χειροκίνητη παρέμβαση.
Κατά τη χρήση προσαρμοσμένης γραμματοσειράς (π.χ. Montserrat), η κλήση preferredFontForTextStyle θα επιστρέψει SF Pro, όχι τη γραμματοσειρά σας. Το UIFontMetrics κλιμακώνει ακριβώς την προσαρμοσμένη γραμματοσειρά, διατηρώντας τον σχεδιασμό της.
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
)
Η μέθοδος scaledFont(for:) δέχεται ένα βασικό UIFont και επιστρέφει μια κλιμακωμένη έκδοση ανάλογη του στυλ .title3. Σε μέγεθος προσβασιμότητας AX5, η γραμματοσειρά Montserrat-Bold 20pt μετατρέπεται σε ~36pt — ακριβώς όσο θα αυξανόταν η γραμματοσειρά συστήματος αυτού του στυλ. Στην IT Sectr, χρησιμοποιούμε αυτό το μοτίβο σε όλα τα έργα με προσαρμοσμένες γραμματοσειρές από το 2018, το οποίο εξάλειψε εντελώς τα παράπονα για μικρό κείμενο από χρήστες με περιορισμένη όραση.
Εάν ενημερώνετε χειροκίνητα τη γραμματοσειρά (χωρίς adjustsFontForContentSizeCategory), εγγραφείτε στην ειδοποίηση UIContentSizeCategory.didChangeNotification. Αυτό είναι απαραίτητο για προσαρμοσμένα στοιχεία UI που δεν κληρονομούν την αυτόματη ενημέρωση γραμματοσειράς.
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)
}
}
Η εγγραφή στο didChangeNotification εγγυάται ότι το προσαρμοσμένο στοιχείο θα ενημερώσει τη γραμματοσειρά σε κάθε αλλαγή των ρυθμίσεων συστήματος χωρίς επανεκκίνηση της εφαρμογής. Από το iOS 15, η ειδοποίηση φτάνει ακόμα και κατά την αλλαγή μεγέθους κειμένου μέσω του Control Center σε εφαρμογές που υποστηρίζουν Live Text Size.
Συχνές ερωτήσεις
Το Dynamic Type είναι διαθέσιμο σε iOS 7 και νεότερες εκδόσεις. Το UIFontMetrics εμφανίστηκε στο iOS 11 — πριν από αυτό χρησιμοποιούνταν απευθείας η μέθοδος preferredFontForTextStyle. Στο iOS 15+, ο δυναμικός τύπος υποστηρίζει επιπλέον μεγέθη προσβασιμότητας (AX1–AX5) για μεγάλες γραμματοσειρές. Οι εφαρμογές που υποστηρίζουν iOS 10 και παλαιότερες εκδόσεις χρησιμοποιούν preferredFontForTextStyle χωρίς UIFontMetrics, γεγονός που περιορίζει την υποστήριξη μόνο στη γραμματοσειρά συστήματος SF Pro.
Στο Xcode 15+, ανοίξτε τον προσομοιωτή και επιλέξτε Settings → Accessibility → Display & Text Size → Larger Text. Σύρετε το ρυθμιστικό για να αλλάξετε το μέγεθος. Στο ίδιο το Xcode υπάρχει το Debug → Accessibility Inspector, το οποίο επισημαίνει στοιχεία με σταθερή γραμματοσειρά. Για αυτοματοποίηση, χρησιμοποιήστε ένα τεστ που αλλάζει το UISlider των ρυθμίσεων μέσω XCUITest — αυτό εγγυάται ότι όλες οι οθόνες ανακατασκευάζονται σωστά.
Ναι, το Auto Layout με δυναμικό τύπο απαιτεί τη χρήση του intrinsicContentSize σε UILabel και UIButton. Σε μεγέθη προσβασιμότητας, το κείμενο μπορεί να υπερβεί τα όρια του superview — προσθέστε UIScrollView ή αυξήστε τους περιορισμούς leading/trailing. Χρησιμοποιήστε το UIFontMetrics.scaledValue για περιθώρια (padding), ώστε τα διαστήματα μεταξύ γραμμάτων να κλιμακώνονται επίσης αναλογικά με τη γραμματοσειρά.
Σύνοψη
Θα αναπτύξουμε μια εφαρμογή για κινητά έτοιμη για χρήση
Η IT Sectr δημιουργεί εφαρμογές iOS και Android για νεοφυείς επιχειρήσεις και επιχειρήσεις από το 2017. Θα σας συμβουλεύσουμε και θα προτείνουμε την καλύτερη λύση.
Διαβάστε επίσης