UIFont και CTFont — είναι κλάσεις για εργασία με γραμματοσειρές στο iOS: UIFont από το UIKit για διαμόρφωση κειμένου υψηλού επιπέδου σε UILabel και UITextView, CTFont από το Core Text για απόδοση χαμηλού επιπέδου με πλήρη έλεγχο γλύφων και μετρήσεων. Σύμφωνα με το Apple Developer Documentation, το UIFont χρησιμοποιείται στο 90% των τυπικών στοιχείων UI, ενώ το CTFont εφαρμόζεται σε προσαρμοσμένες μηχανές κειμένου και επεξεργαστές. Και οι δύο κλάσεις αντιπροσωπεύουν την ίδια γραμματοσειρά, αλλά σε διαφορετικό επίπεδο αφαίρεσης.
Κύρια σημεία
UIFont — είναι μια κλάση UIKit που αντιπροσωπεύει μια γραμματοσειρά για την εμφάνιση κειμένου σε στοιχεία UI: UILabel, UITextView, UITextField. Παρέχει μια απλή διεπαφή για λήψη συστημικών και προσαρμοσμένων γραμματοσειρών με καθορισμό μεγέθους, βάρους και στυλ. Το UIFont δεν επιτρέπει την άμεση διαχείριση kerning, ligature και λειτουργιών OpenType — για αυτό χρησιμοποιείται το Core Text.
CTFont — είναι ένας τύπος Core Text (CTFontRef) που παρέχει πρόσβαση χαμηλού επιπέδου στα δεδομένα γραμματοσειράς. Το CTFont λειτουργεί απευθείας με το Core Graphics για απόδοση, υποστηρίζει όλες τις δυνατότητες OpenType και TrueType, συμπεριλαμβανομένων εναλλακτικών γλύφων, ligature και μεταβλητών γραμματοσειρών. Το CTFont χρησιμοποιείται εσωτερικά από το UIKit για την απόδοση του UIFont, αλλά είναι επίσης άμεσα διαθέσιμο για προσαρμοσμένη σχεδίαση.
Τα UIFont και CTFont υποστηρίζουν toll-free bridging — μετατροπή μεταξύ τύπων χωρίς επιπλέον κόστος. Το casting UIFont as CTFont ή CTFont as UIFont είναι δυνατό σε Swift και Objective-C. Αυτό επιτρέπει τη χρήση του UIKit API υψηλού επιπέδου για διαμόρφωση και του Core Text χαμηλού επιπέδου για απόδοση χωρίς αντιγραφή δεδομένων γραμματοσειράς.
Και οι δύο κλάσεις χρησιμοποιούν το UIFontDescriptor (UIKit) / CTFontDescriptor (Core Text) για την περιγραφή χαρακτηριστικών γραμματοσειράς: όνομα, μέγεθος, βάρος, στυλ, πίνακα μετασχηματισμού. Ο περιγραφέας είναι ένα λεξικό χαρακτηριστικών που μπορεί να τροποποιηθεί για να δημιουργήσει νέες γραμματοσειρές βάσει υπαρχουσών. Για παράδειγμα, προσθέστε traitItalic σε έναν περιγραφέα και λάβετε την πλάγια έκδοση της ίδιας γραμματοσειράς.
UIFont παρέχει αρκετές εργοστασιακές μεθόδους για δημιουργία γραμματοσειρών. Η systemFont(ofSize:) επιστρέφει τη συστημική γραμματοσειρά San Francisco (iOS) ή Helvetica (παλαιότερες εκδόσεις). Οι boldSystemFont, italicSystemFont — παραλλαγές με στυλ. Η preferredFont(forTextStyle:) επιστρέφει γραμματοσειρά Dynamic Type για το δεδομένο στυλ: .headline, .body, .caption1, .footnote. Αυτές οι γραμματοσειρές κλιμακώνονται αυτόματα όταν αλλάζουν οι ρυθμίσεις μεγέθους κειμένου στο σύστημα.
Για φόρτωση προσαρμοσμένων γραμματοσειρών χρησιμοποιείται το UIFont(name:size:) με το όνομα PostScript της γραμματοσειράς. Η γραμματοσειρά πρέπει να έχει προστεθεί στο Info.plist και να συμπεριλαμβάνεται στο bundle της εφαρμογής. Σύμφωνα με την Apple, συνιστάται η χρήση του UIFont για όλα τα τυπικά στοιχεία UI και η μετάβαση στο CTFont μόνο όταν απαιτείται προσαρμοσμένη απόδοση.
Dynamic Type — προσαρμοστικό σύστημα γραμματοσειρών που εισήχθη στο iOS 7. Ο χρήστης επιλέγει το προτιμώμενο μέγεθος κειμένου στις Ρυθμίσεις — από πολύ μικρό έως πολύ μεγάλο. Το UIFont.preferredFont επιστρέφει αυτόματα γραμματοσειρά κατάλληλου μεγέθους. Για σωστή λειτουργία, όλα τα UILabel πρέπει να έχουν adjustsFontForContentSizeCategory = true. Το Dynamic Type είναι υποχρεωτικό για συμβατότητα προσβασιμότητας.
UIFontDescriptor επιτρέπει την τροποποίηση χαρακτηριστικών γραμματοσειράς χωρίς δημιουργία νέου στιγμιότυπου από την αρχή. Οι μέθοδοι addingAttributes(_:), withSymbolicTraits(_:), withFamily(_:) επιστρέφουν έναν νέο περιγραφέα με τροποποιημένες παραμέτρους. Αυτό είναι βολικό για λήψη παραλλαγών γραμματοσειράς: προσθέστε traitBold σε μια συστημική γραμματοσειρά και λάβετε την έντονη έκδοση χωρίς να γνωρίζετε το όνομα PostScript.
CTFont (CTFontRef) — είναι ένας τύπος Core Text για εργασία χαμηλού επιπέδου με γραμματοσειρές. Δημιουργείται με τις συναρτήσεις CTFontCreateWithName, CTFontCreateWithFontDescriptor, CTFontCreateCopyWithAttributes. Κάθε συνάρτηση επιστρέφει μια γραμματοσειρά με καθορισμένη διεπαφή, μέγεθος και προαιρετικά χαρακτηριστικά. Το CTFont χρησιμοποιείται στο Core Graphics για απόδοση κειμένου σε προσαρμοσμένα UIView μέσω drawRect.
Το CTFont παρέχει πρόσβαση σε μετρήσεις που δεν είναι διαθέσιμες στο UIFont: η CTFontGetGlyphsForCharacters επιστρέφει έναν πίνακα γλύφων για δεδομένους χαρακτήρες, η CTFontGetAdvancesForGlyphs — το πλάτος κάθε γλύφου, η CTFontGetBoundingBox — τα όρια του γλύφου. Αυτό είναι απαραίτητο για την κατασκευή προσαρμοσμένων διατάξεων κειμένου: στήλες, περιστροφή, περιτύλιξη.
Οι CTFontGetAscent, CTFontGetDescent, CTFontGetLeading επιστρέφουν κάθετες μετρήσεις της γραμματοσειράς. CTFontGetUnitsPerEm — αριθμός μονάδων ανά em-square, χρησιμοποιείται για υπολογισμό αναλογιών. CTFontGetGlyphCount — συνολικός αριθμός γλύφων στη γραμματοσειρά. Αυτά τα δεδομένα είναι κρίσιμα για τυπογραφία εκτύπωσης και προσαρμοσμένες στοιχειοθεσίες όπου απαιτείται ακριβής τοποθέτηση κάθε χαρακτήρα.
CTFont υποστηρίζει λειτουργίες OpenType: η CTFontCopyFeatures επιστρέφει ένα λεξικό διαθέσιμων λειτουργιών γραμματοσειράς (ligature, εναλλακτικοί χαρακτήρες, kerning), η CTFontEnableFeature ενεργοποιεί μια συγκεκριμένη επιλογή. Οι μεταβλητές γραμματοσειρές (Variable Fonts) διαμορφώνονται μέσω CTFontCopyVariation και CTFontCreateCopyWithVariation, επιτρέποντας αλλαγή των weight, width και slant σε συνεχές εύρος.
Η δημιουργία UIFont σε Swift γίνεται μέσω μιας από τις εργοστασιακές μεθόδους ή άμεσης αρχικοποίησης με όνομα. Η πιο κοινή μέθοδος είναι systemFont(ofSize:weight:) για συστημικές γραμματοσειρές ή preferredFont(forTextStyle:) για Dynamic Type. Για προσαρμοσμένες γραμματοσειρές χρησιμοποιείται UIFont(name:size:) με αναφορά του ονόματος PostScript.
Η UIFont.systemFont(ofSize:weight:) δέχεται UIFont.Weight — από .ultraLight έως .black. Αυτή η μέθοδος επιστρέφει τη συστημική γραμματοσειρά San Francisco με το αντίστοιχο βάρος. Οι UIFont.monospacedSystemFont, UIFont.monospacedDigitSystemFont επιστρέφουν γραμματοσειρές σταθερού πλάτους για κώδικα και αριθμούς. Όλες οι συστημικές γραμματοσειρές υποστηρίζουν αυτόματα το Dynamic Type.
let regularFont = UIFont.systemFont(ofSize: 16, weight: .regular)
let boldFont = UIFont.systemFont(ofSize: 16, weight: .bold)
let headlineFont = UIFont.preferredFont(forTextStyle: .headline)
let monoFont = UIFont.monospacedSystemFont(ofSize: 14, weight: .regular)
label.font = headlineFont
Κάθε γραμματοσειρά μπορεί να αντιστοιχιστεί άμεσα στην ιδιότητα font ενός UILabel ή να χρησιμοποιηθεί σε NSAttributedString μέσω NSFontAttributeName. Οι συστημικές γραμματοσειρές αποθηκεύονται στην κρυφή μνήμη από το iOS, επομένως η εκ νέου δημιουργία μιας συστημικής γραμματοσειράς δεν συνεπάγεται επιπλέον κόστος.
Για χρήση προσαρμοσμένης γραμματοσειράς, προσθέστε το αρχείο TTF ή OTF στο bundle του έργου και καθορίστε το στο Info.plist (UIAppFonts). Το όνομα PostScript της γραμματοσειράς μπορεί να βρεθεί μέσω UIFont.familyNames και UIFont.fontNames(forFamilyName:). Μετά την εγγραφή, η γραμματοσειρά είναι διαθέσιμη μέσω UIFont(name:size:) σε οποιοδήποτε σημείο της εφαρμογής.
// Λήψη όλων των ονομάτων οικογενειών γραμματοσειρών
for family in UIFont.familyNames {
let names = UIFont.fontNames(forFamilyName: family)
print("\(οικογένεια): \(ονόματα)")
}
// Φόρτωση προσαρμοσμένης γραμματοσειράς
if let customFont = UIFont(name: "MyCustomFont-Regular", size: 18) {
label.font = customFont
}
Εάν το όνομα της γραμματοσειράς είναι λανθασμένο, το UIFont(name:size:) επιστρέφει nil. Συνιστάται η εκ των προτέρων εμφάνιση όλων των διαθέσιμων ονομάτων γραμματοσειρών μέσω UIFont.familyNames και UIFont.fontNames(forFamilyName:) κατά τον εντοπισμό σφαλμάτων για να βεβαιωθείτε ότι η γραμματοσειρά έχει εγγραφεί σωστά.
Η φόρτωση προσαρμοσμένων γραμματοσειρών είναι δυνατή με δύο τρόπους: στατική εγγραφή μέσω Info.plist (UIAppFonts) και δυναμική εγγραφή μέσω CTFontManagerRegisterGraphicsFont. Ο πρώτος τρόπος είναι απλούστερος — η γραμματοσειρά είναι διαθέσιμη αμέσως μετά την εκκίνηση της εφαρμογής. Ο δεύτερος χρησιμοποιείται για γραμματοσειρές που φορτώνονται από το δίκτυο ή μεταφορτώνονται κατόπιν ζήτησης.
Η δυναμική εγγραφή είναι χρήσιμη για πόρους κατόπιν ζήτησης: εάν η εφαρμογή περιέχει 20+ γραμματοσειρές, δεν χρειάζεται να συμπεριληφθούν όλες στο αρχικό bundle, αλλά μπορούν να μεταφορτωθούν κατά την πρώτη χρήση. Η CTFontManagerRegisterFontsForURLs εγγράφει γραμματοσειρές από καθορισμένα URL. Μετά την εγγραφή, η γραμματοσειρά γίνεται διαθέσιμη μέσω UIFont(name:size:) ως συνήθως.
Για προσαρμοσμένη απόδοση μέσω Core Text χρησιμοποιήστε το CTFontCreateWithName με το όνομα PostScript της γραμματοσειράς. Η διαφορά από το UIFont είναι ότι το CTFont μπορεί να δημιουργηθεί με πίνακα μετασχηματισμού (CTFontCreateWithNameAndOptions) — για δημιουργία παραμορφωμένων γραμματοσειρών: κλίση, κλιμάκωση στον άξονα Χ, περιστροφή. Αυτό δεν είναι διαθέσιμο στο UIFont χωρίς χρήση συγγενικών μετασχηματισμών.
// Δημιουργία CTFont με πίνακα κλίσης
var matrix = CGAffineTransform(a: 1, b: 0, c: 0.2, d: 1, tx: 0, ty: 0)
let ctFont = CTFontCreateWithName(
"Helvetica" as CFString,
24, &matrix)
// Χρήση toll-free bridging με UIFont
let uiFont = ctFont as UIFont
label.font = uiFont
Ο πίνακας μετασχηματισμού επιτρέπει τη δημιουργία italic παραλλαγών χωρίς ξεχωριστό αρχείο γραμματοσειράς. Η παράμετρος c (skew) προσθέτει κλίση στους χαρακτήρες. Ο πίνακας επιτρέπει επίσης την οριζόντια κλιμάκωση της γραμματοσειράς — δημιουργώντας συμπιεσμένες ή διευρυμένες παραλλαγές της ίδιας γραμματοσειράς.
Η κύρια διαφορά μεταξύ UIFont και CTFont είναι το επίπεδο αφαίρεσης. Το UIFont παρέχει ένα απλό API για κοινές εργασίες: λήψη συστημικής γραμματοσειράς, αλλαγή μεγέθους, εφαρμογή σε UILabel. Το CTFont δίνει πλήρη έλεγχο της γραμματοσειράς: πρόσβαση σε γλύφους, μετρήσεις, πίνακες OpenType και μεταβλητούς άξονες. Η επιλογή εξαρτάται από την εργασία.
| Χαρακτηριστικό | UIFont | CTFont |
|---|---|---|
| Πλαίσιο | UIKit | Core Text |
| Δημιουργία | systemFont / preferredFont / initWithName | CTFontCreateWithName / CTFontCreateWithDescriptor |
| Πρόσβαση σε γλύφους | Όχι | CTFontGetGlyphsForCharacters |
| Λειτουργίες OpenType | Περιορισμένη (UIFontDescriptor) | Πλήρης πρόσβαση |
| Μεταβλητές γραμματοσειρές | Μέσω UIFontDescriptor | CTFontCopyVariation / CreateCopyWithVariation |
| Απόδοση | Αυτόματη σε στοιχεία UI | Core Graphics, προσαρμοσμένη |
Για το 95% των εργασιών ανάπτυξης iOS, το UIFont είναι επαρκές. Το Core Text με CTFont δικαιολογείται κατά τη δημιουργία επεξεργαστών κειμένου, γεννητριών PDF, βιβλίων με τυπογραφική στοιχειοθεσία ή εφαρμογών με προσαρμοσμένη εμφάνιση σπάνιων γλωσσών.
Η εργασία με γραμματοσειρές στο iOS απαιτεί να λαμβάνεται υπόψη η απόδοση. Κάθε μοναδική γραμματοσειρά φορτώνεται στη μνήμη κατά την πρώτη χρήση και καταλαμβάνει πόρους. Οι συστημικές γραμματοσειρές San Francisco είναι προφορτωμένες και δεν δημιουργούν επιπλέον κόστος. Οι προσαρμοσμένες γραμματοσειρές φορτώνονται από αρχείο και αποθηκεύονται στην κρυφή μνήμη από το σύστημα μετά την πρώτη φόρτωση.
Συνιστάται ο περιορισμός του αριθμού μοναδικών γραμματοσειρών στην εφαρμογή σε 3-5 οικογένειες. Κάθε γραμματοσειρά καταλαμβάνει από 50 KB έως 2 MB στη μνήμη. Η χρήση διαφορετικών βαρών της ίδιας οικογένειας (regular, bold, medium) είναι πιο αποδοτική από τη φόρτωση πολλών διαφορετικών οικογενειών.
Το σύστημα αποθηκεύει προσωρινά τα δημιουργημένα στιγμιότυπα UIFont, επομένως οι επαναλαμβανόμενες κλήσεις UIFont.systemFont(ofSize: 16, weight: .regular) δεν δημιουργούν νέο αντικείμενο. Ωστόσο, το UIFont(name:size:) για προσαρμοσμένες γραμματοσειρές δεν αποθηκεύεται πάντα προσωρινά — συνιστάται η αποθήκευση συχνά χρησιμοποιούμενων γραμματοσειρών σε στατικές ιδιότητες ή προσωρινή μνήμη NSCache για αποφυγή επαναλαμβανόμενης φόρτωσης από το αρχείο.
Κατά τη δυναμική εγγραφή γραμματοσειρών μέσω CTFontManagerRegisterGraphicsFont, η διαδικασία μπορεί να είναι ασύγχρονη εάν το αρχείο γραμματοσειράς μεταφορτώνεται από το δίκτυο. Σε αυτήν την περίπτωση, το UILabel ή UITextView πρέπει να εμφανίζουν μια εφεδρική συστημική γραμματοσειρά μέχρι να ολοκληρωθεί η φόρτωση. Μετά την εγγραφή, η γραμματοσειρά γίνεται διαθέσιμη και η οθόνη ενημερώνει αυτόματα την εμφάνιση κειμένου.
Συχνές Ερωτήσεις
Ναι, τα UIFont και CTFont υποστηρίζουν toll-free bridging. Η μετατροπή γίνεται με απλό casting: UIFont as CTFont ή CTFont as UIFont. Δεν υπάρχει επιπλέον κόστος ή αντιγραφή δεδομένων — και οι δύο κλάσεις δείχνουν στο ίδιο αντικείμενο γραμματοσειράς στη μνήμη.
Για όλα τα στοιχεία UI χρησιμοποιήστε το UIFont. Είναι βελτιστοποιημένο για UIKit, υποστηρίζει Dynamic Type, κλιμακώνεται σωστά όταν αλλάζουν οι ρυθμίσεις συστήματος. Το CTFont δικαιολογείται μόνο για προσαρμοσμένη απόδοση μέσω Core Graphics ή όταν απαιτείται πρόσβαση σε μετρήσεις γραμματοσειράς χαμηλού επιπέδου.
Χρησιμοποιήστε το UIFont.familyNames για λίστα οικογενειών και UIFont.fontNames(forFamilyName:) για ονόματα PostScript. Καλέστε αυτόν τον κώδικα σε λειτουργία εντοπισμού σφαλμάτων και βρείτε την επιθυμητή γραμματοσειρά. Το όνομα PostScript συνήθως περιέχει το όνομα οικογένειας και το στυλ: “SFProText-Regular”, “HelveticaNeue-Bold”.
Ναι, μέσω του UIFontDescriptor μπορούν να ρυθμιστούν μεταβλητοί άξονες: weight, width, slant. Ωστόσο, το API του UIFont για μεταβλητές γραμματοσειρές είναι περιορισμένο σε σύγκριση με το CTFontCopyVariation. Για πλήρη έλεγχο των μεταβλητών αξόνων χρησιμοποιήστε το Core Text και το CTFontCreateCopyWithVariation.
Δημιουργήστε ένα στατικό λεξικό ή NSCache με κλειδί από συνδυασμό ονόματος και μεγέθους. Για συστημικές γραμματοσειρές, το iOS αποθηκεύει προσωρινά τα στιγμιότυπα αυτόματα, αλλά για προσαρμοσμένες γραμματοσειρές που δημιουργούνται μέσω UIFont(name:size:), συνιστάται η αποθήκευση αντικειμένων στην κρυφή μνήμη της εφαρμογής για αποφυγή επαναλαμβανόμενης φόρτωσης από το αρχείο TTF.
Σύνοψη
Θα αναπτύξουμε μια εφαρμογή για κινητά έτοιμη για χρήση
Η IT Sectr δημιουργεί εφαρμογές iOS και Android για νεοφυείς επιχειρήσεις και επιχειρήσεις από το 2017. Θα σας συμβουλεύσουμε και θα προτείνουμε την καλύτερη λύση.
Διαβάστε επίσης