Dynamic Type — ενσωματωμένη λειτουργία του iOS που αλλάζει αυτόματα το μέγεθος γραμματοσειράς στην εφαρμογή σύμφωνα με τις ρυθμίσεις συστήματος του χρήστη. Ο χρήστης ορίζει το προτιμώμενο μέγεθος κειμένου στις Ρυθμίσεις → Οθόνη και φωτεινότητα → Μέγεθος κειμένου, και όλες οι εφαρμογές που υποστηρίζουν Dynamic Type προσαρμόζονται χωρίς πρόσθετες ενέργειες. Σύμφωνα με το Apple Human Interface Guidelines, 2024, η υποστήριξη Dynamic Type είναι υποχρεωτική απαίτηση για δημοσίευση στο App Store, καθώς αποτελεί βασικό στοιχείο προσβασιμότητας στην πλατφόρμα iOS.
Βασικά σημεία
Dynamic Type — τεχνολογία του iOS, που εμφανίστηκε στο iOS 7, η οποία επιτρέπει στο κείμενο της εφαρμογής να προσαρμόζεται αυτόματα στις ρυθμίσεις μεγέθους γραμματοσειράς συστήματος. Ο χρήστης μπορεί να αυξήσει ή να μειώσει τη γραμματοσειρά σε όλες τις εφαρμογές ταυτόχρονα — χωρίς να χρειάζεται να αλλάξει ρυθμίσεις μέσα σε κάθε εφαρμογή ξεχωριστά.
Σύμφωνα με το Apple WWDC 2023, «Make Your App Visually Accessible», περισσότεροι από 40% των χρηστών iOS αλλάζουν το μέγεθος γραμματοσειράς από το προεπιλεγμένο. Για την ηλικιακή ομάδα 65+ αυτό το ποσοστό φτάνει το 70%. Το Dynamic Type είναι υποχρεωτική απαίτηση για πιστοποίηση προσβασιμότητας στο App Store. Η έλλειψη υποστήριξης αποτελεί λόγο απόρριψης της εφαρμογής στον έλεγχο.
Αρχή λειτουργίας: η εφαρμογή χρησιμοποιεί UIFont.preferredFont(forTextStyle:) αντί για UIFont(name:size:). Το iOS επιστρέφει αυτόματα γραμματοσειρά κλιμακωμένη σύμφωνα με την τρέχουσα ρύθμιση συστήματος. Κατά την αλλαγή μεγέθους στις ρυθμίσεις, το iOS δημιουργεί ειδοποίηση UIContentSizeCategory.didChangeNotification — η εφαρμογή πρέπει να υπολογίσει ξανά τη διάταξη.
Το Dynamic Type εμφανίστηκε στο iOS 7 μαζί με τον επίπεδο σχεδιασμό. Στο iOS 10 προστέθηκε υποστήριξη για προσαρμοσμένες γραμματοσειρές μέσω UIFontMetrics. Το iOS 11 εισήγαγε επίπεδα προσβασιμότητας (έως AccessibilityXXXL). Το iOS 15 πρόσθεσε το Dynamic Type στο SwiftUI με αυτόματη υποστήριξη. Με κάθε έκδοση η Apple ενισχύει τις απαιτήσεις: από το iOS 17, οι εφαρμογές χωρίς υποστήριξη Dynamic Type λαμβάνουν προειδοποίηση κατά τη μεταφόρτωση στο App Store Connect.
Το iOS παρέχει 8 στυλ κειμένου, το καθένα με προκαθορισμένο μέγεθος και γραφή για την τυπική ρύθμιση:
| Στυλ | Σταθερά | Μέγεθος (L) | Χρήση |
|---|---|---|---|
| Large Title | .largeTitle | 34px | Κύριος τίτλος οθόνης |
| Title 1 | .title1 | 28px | Τίτλος ενότητας |
| Title 2 | .title2 | 22px | Υπότιτλος |
| Title 3 | .title3 | 20px | Τίτλος κάρτας |
| Headline | .headline | 17px (bold) | Έντονο για εμφάσεις |
| Body | .body | 17px | Κύριο κείμενο |
| Callout | .callout | 16px | Βοηθητικό κείμενο |
| Caption 1 | .caption1 | 12px | Λεζάντα κάτω από εικόνα |
| Caption 2 | .caption2 | 11px | Μικρή λεζάντα |
| Footnote | .footnote | 13px | Υποσημείωση, σημείωση |
Η χρήση του σωστού στυλ δεν είναι απλά θέμα εμφάνισης. UIFont.TextStyle.body σε λειτουργία AccessibilityXXXL μπορεί να φτάσει τα 53px. Αν η εφαρμογή χρησιμοποιεί σταθερή γραμματοσειρά 17px για body, το κείμενο θα γίνει μη αναγνώσιμο για χρήστες που έχουν αυξήσει τη γραμματοσειρά.
Το Dynamic Type όχι μόνο κλιμακώνει — διατηρεί την οπτική ιεραρχία. Το Large Title είναι πάντα μεγαλύτερο από το Title 1, το οποίο είναι μεγαλύτερο από το Body, ανεξάρτητα από το επίπεδο κλιμάκωσης. Οι συντελεστές κλιμάκωσης διαφέρουν: οι τίτλοι κλιμακώνονται πιο έντονα από το κύριο κείμενο, ώστε η ιεραρχία να διατηρείται ακόμα και σε επίπεδα προσβασιμότητας.
Το iOS υποστηρίζει 11 επίπεδα κλιμάκωσης κειμένου, χωρισμένα σε δύο κατηγορίες:
Η διαφορά μεταξύ XS και AccessibilityXXXL για το στυλ body είναι από 14px έως 53px — σχεδόν 4×. Η διάταξη που έχει σχεδιαστεί για 17px καταρρέει εντελώς στα 53px: το κείμενο βγαίνει εκτός ορίων, τα κουμπιά επικαλύπτονται, τα κελιά συγκρούονται μεταξύ τους.
Ελέγξτε την τρέχουσα κατηγορία στον κώδικα:
let category = UIApplication.shared.preferredContentSizeCategory
// .extraSmall, .small, .medium, .large, .extraLarge ...
if category.isAccessibilityCategory {
// Ενεργοποίηση εναλλακτικής διάταξης
}
Η κατηγορία μεγέθους κειμένου είναι διαθέσιμη μέσω traitCollection.uiContentSizeCategory. Κατά την αλλαγή της ρύθμισης συστήματος, το iOS καλεί traitCollectionDidChange σε όλα τα UIView. Σε αυτή τη μέθοδο πρέπει να ενημερώσετε τις γραμματοσειρές και να υπολογίσετε ξανά τη διάταξη. Το SwiftUI το κάνει αυτόματα — το UIKit απαιτεί χειροκίνητη εγγραφή.
Για UICollectionView χρησιμοποιήστε UICollectionViewCompositionalLayout — προσαρμόζει αυτόματα τον αριθμό στηλών στο πλάτος οθόνης και το μέγεθος κειμένου. Σε επίπεδα προσβασιμότητας, μεταβείτε από διάταξη δύο στηλών σε μονή στήλη, ώστε το κείμενο να μην κόβεται και τα στοιχεία να μην επικαλύπτονται. Χρησιμοποιήστε conditional layout: για regular width — δύο στήλες, για compact ή accessibility — μία στήλη.
Βασική υλοποίηση στο UIKit — UIFont.preferredFont(forTextStyle:). Αυτή η μέθοδος επιστρέφει γραμματοσειρά κλιμακωμένη σύμφωνα με την τρέχουσα ρύθμιση συστήματος:
titleLabel.font = UIFont.preferredFont(forTextStyle: .headline)
bodyLabel.font = UIFont.preferredFont(forTextStyle: .body)
Για προσαρμοσμένες γραμματοσειρές χρησιμοποιήστε UIFontMetrics:
let customFont = UIFont(name: "Montserrat-Regular", size: 16)!
titleLabel.font = UIFontMetrics(forTextStyle: .body)
.scaledFont(for: customFont)
// Παρακολούθηση αλλαγών μεγέθους
NotificationCenter.default.addObserver(
self,
selector: #selector(preferredContentSizeChanged),
name: UIContentSizeCategory.didChangeNotification,
object: nil
)
Για UILabel στο Interface Builder αρκεί να ορίσετε τη γραμματοσειρά ως στυλ κειμένου (Text Style) και να ενεργοποιήσετε το «Automatically Adjusts Font». Για προσαρμοσμένες γραμματοσειρές το IB δεν υποστηρίζει UIFontMetrics — μόνο μέσω κώδικα.
Το UIFontMetrics χρησιμοποιεί την ίδια scaling curve με το preferredFont. Μπορείτε να ορίσετε fromTextStyle: .body, .headline κ.λπ. Κάθε στυλ έχει τον δικό του συντελεστή κλιμάκωσης. Το Body κλιμακώνεται μέτρια, το Large Title — επιθετικά. Αν η προσαρμοσμένη γραμματοσειρά σας χρησιμοποιείται για κύριο κείμενο, χρησιμοποιήστε .body.
Στο SwiftUI η υποστήριξη Dynamic Type είναι ενσωματωμένη από προεπιλογή. Όλοι οι τροποποιητές συστήματος (.font(.body), .font(.title)) κλιμακώνονται αυτόματα. Ο προγραμματιστής δεν χρειάζεται να καλέσει UIFont.preferredFont.
Παράδειγμα:
Text("Κύριο κείμενο")
.font(.body)
.lineLimit(nil)
.minimumScaleFactor(0.5)
Για προσαρμοσμένες κλίμακες χρησιμοποιήστε DynamicTypeSize:
@Environment(\.dynamicTypeSize) var dynamicTypeSize
var body: some View {
Text("Προσαρμοστικό κείμενο")
.font(.body)
.padding(dynamicTypeSize <= .large ? 8 : 16)
}
Το SwiftUI ενημερώνει αυτόματα την προβολή όταν αλλάζει το μέγεθος κειμένου συστήματος — χωρίς πρόσθετες εγγραφές σε ειδοποιήσεις.
Ο τροποποιητής .font(.body) λειτουργεί μόνο για γραμματοσειρά συστήματος. Για προσαρμοσμένες γραμματοσειρές στο SwiftUI χρησιμοποιήστε Font.custom με UIFontMetrics στο παρασκήνιο. Από το iOS 16, το SwiftUI υποστηρίζει DynamicTypeSize στο @Environment, επιτρέποντας την προσαρμογή αποστάσεων και διάταξης.
Auto Layout — υποχρεωτική προϋπόθεση για υποστήριξη Dynamic Type. Τα σταθερά πλάτη και ύψη (>=, <=) σπάνε σε μεγέθη προσβασιμότητας. Χρησιμοποιήστε intrinsicContentSize για UILabel — υπολογίζει αυτόματα το ύψος βάσει του τρέχοντος μεγέθους γραμματοσειράς.
Κανόνες προσαρμοστικής διάταξης:
Για μεγάλα κείμενα (π.χ. άρθρα, όροι χρήσης) ορίστε minimumScaleFactor στο UILabel — μειώνει το κείμενο ως έσχατη λύση όταν το Auto Layout δεν μπορεί να χωρέσει το περιεχόμενο. Η τιμή 0.5 σημαίνει ότι η γραμματοσειρά μπορεί να μειωθεί έως 50% του προτιμώμενου μεγέθους.
Παράδειγμα προσαρμογής περιθωρίων βάσει κατηγορίας μεγέθους:
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)
Κοπή κειμένου — UILabel με numberOfLines = 1 και σταθερό πλάτος κόβει το κείμενο στο AccessibilityXL. Λύση: numberOfLines = 0 και trailing constraint. Επικάλυψη στοιχείων — κουμπιά με σταθερό ύψος συγκρούονται. Λύση: UIStackView με automatic spacing. Έξοδος εκτός ορίων οθόνης — το ScrollView είναι υποχρεωτικό για επίπεδα προσβασιμότητας.
Προσομοιωτής Xcode επιτρέπει την αλλαγή μεγέθους κειμένου: στο μενού του προσομοιωτή Settings → Accessibility → Display & Text Size → Larger Text. Εναλλάξτε μεταξύ όλων των 11 επιπέδων και ελέγξτε ότι το κείμενο δεν κόβεται, τα κουμπιά είναι προσβάσιμα, η διάταξη δεν σπάει.
Για αυτοματοποιημένη δοκιμή χρησιμοποιήστε τη ρύθμιση contentSizeCategory στο XCUIApplication:
func testAccessibilitySizes() {
let app = XCUIApplication()
app.launchArguments += [
"-UIPreferredContentSizeCategoryName",
"UICTContentSizeCategoryAccessibilityXXXL"
]
app.launch()
app.scrollViews.buttons["Αποστολή"].tap()
XCTAssertTrue(app.staticTexts["Η φόρμα υποβλήθηκε"]
.waitForExistence(timeout: 5))
}
XCUITest με διαφορετικά launchArguments επιτρέπει τον έλεγχο όλων των επιπέδων κλιμάκωσης στο CI. Μην ξεχάσετε να ελέγξετε τις κατηγορίες προσβασιμότητας ξεχωριστά — συνήθως σπάνε τη διάταξη. Σύμφωνα με την Apple, το 70% των σφαλμάτων Dynamic Type εντοπίζονται ακριβώς σε επίπεδα προσβασιμότητας, επειδή οι προγραμματιστές δοκιμάζουν μόνο τα τυπικά μεγέθη.
Το Xcode Accessibility Inspector δείχνει ποιες γραμματοσειρές χρησιμοποιεί το επιλεγμένο στοιχείο — σταθερή ή κλιμακούμενη. Αν το στοιχείο δεν αντιδρά στην αλλαγή μεγέθους κειμένου στον προσομοιωτή, σημαίνει ότι χρησιμοποιείται σταθερή γραμματοσειρά. Αντικαταστήστε με UIFont.preferredFont ή UIFontMetrics.
Συχνές ερωτήσεις
Είναι αυτόματη κλιμάκωση κειμένου στην εφαρμογή βάσει των ρυθμίσεων μεγέθους συστήματος. Ο χρήστης αλλάζει το μέγεθος στις Ρυθμίσεις — όλες οι εφαρμογές που το υποστηρίζουν προσαρμόζονται χωρίς παρέμβαση του προγραμματιστή.
Όχι. Για προσαρμοσμένες γραμματοσειρές χρησιμοποιήστε UIFontMetrics(scaledFont:). Η μέθοδος κλιμακώνει οποιαδήποτε γραμματοσειρά σε σχέση με το καθορισμένο στυλ κειμένου, διατηρώντας τις αναλογίες.
11 επίπεδα: 5 τυπικά (XS, S, M, L, XL) και 6 επίπεδα προσβασιμότητας (από AccessibilityXL έως AccessibilityXXXXXL). Το μέγεθος γραμματοσειράς body μπορεί να κυμαίνεται από 14px έως 53px.
Στο UIKit μέσω UIContentSizeCategory.didChangeNotification. Στο SwiftUI χρησιμοποιήστε @Environment(\.dynamicTypeSize) — η προβολή θα ενημερωθεί αυτόματα κατά την αλλαγή της ρύθμισης συστήματος.
Οι χρήστες με αυξημένη γραμματοσειρά θα δουν κομμένο κείμενο, επικαλυπτόμενα στοιχεία και μη λειτουργικά κουμπιά. Η εφαρμογή μπορεί να απορριφθεί στο App Store Review λόγω παραβίασης απαιτήσεων προσβασιμότητας.
Σύνοψη
Θα αναπτύξουμε μια εφαρμογή για κινητά έτοιμη για χρήση
Η IT Sectr δημιουργεί εφαρμογές iOS και Android για νεοφυείς επιχειρήσεις και επιχειρήσεις από το 2017. Θα σας συμβουλεύσουμε και θα προτείνουμε την καλύτερη λύση.
Διαβάστε επίσης