Custom Font — este un fișier de font (TTF, OTF, WOFF2) pe care dezvoltatorul îl adaugă în aplicația mobilă pentru a înlocui fontul de sistem implicit. Fonturile personalizate sunt utilizate pentru crearea unui stil vizual unic, conformitatea cu ghidul de brand și îmbunătățirea lizibilității în diferite limbi. Conform datelor Apple Fonts, fonturile personalizate sunt suportate pe toate platformele Apple, iar Android oferă mecanismul Font Family pentru simplificarea încărcării. Conectarea corectă a fontului influențează critic tipografia și percepția generală a aplicației.
Principalele aspecte
Custom Font (font personalizat) — este un fișier cu un caracter care nu face parte din setul standard de fonturi al sistemului de operare. Dezvoltatorii adaugă astfel de fonturi în proiect pentru o tipografie unică, conformă cu brandul. Fonturile personalizate pot fi atât caractere comerciale plătite, cât și fonturi gratuite open-source, de exemplu, Inter, Montserrat, Roboto (versiune personalizată).
Scenarii tipice de utilizare a fonturilor personalizate: logo-uri și titluri ale aplicațiilor de brand, aplicații de citire cu cerințe speciale de tipografie, jocuri cu fonturi tematice, aplicații pentru limbi non-latine, unde fontul de sistem nu suportă glifele necesare. Conform datelor Google Fonts, peste 60% din aplicațiile din top-100 personalizează fonturile pentru diferențiere vizuală.
Fonturile de sistem (San Francisco pe iOS, Roboto pe Android) sunt optimizate pentru interfețe, dar nu sunt potrivite pentru tipografia de brand. Fontul personalizat întărește recunoașterea brandului, poate conține simboluri speciale (fonturi iconice) și îmbunătățește lizibilitatea pentru audiențe specifice. Cu toate acestea, utilizarea excesivă a diferitelor fonturi înrăutățește UX — se recomandă nu mai mult de 2-3 familii per aplicație.
Platformele mobile suportă mai multe formate de fonturi. TrueType (TTF) — cel mai răspândit format, compatibil cu toate versiunile de iOS și Android. OpenType (OTF) — extensie a TTF cu suport pentru ligaturi, glife alternative și funcții OpenType. Ambele formate au extensiile .ttf și .otf și funcționează identic pe platformele mobile.
WOFF2 (Web Open Font Format 2) — format comprimat pentru web, suportat în Android de la versiunea 10. WOFF2 oferă compresie de 30-50% față de TTF. Pentru iOS, WOFF2 este suportat prin Safari, dar în aplicațiile native este necesară conversia în TTF/OTF. Variable Fonts (fonturi variabile) — un format modern care stochează toate caracterele într-un singur fișier.
| Format | iOS | Android | Compresie | Caracteristici |
|---|---|---|---|---|
| TTF | Da | Da | Nu | Format standard, compatibilitate largă |
| OTF | Da | Da | Nu | Funcții OpenType, ligaturi, glife alternative |
| WOFF2 | Prin Safari | API 29+ | 30-50% | Comprimat, pentru economisirea dimensiunii APK |
| Variable | iOS 11+ | API 29+ | Ridicată | Un singur fișier pentru toate caracterele |
Pentru dezvoltarea mobilă se recomandă utilizarea OTF ca format principal — suportă funcțiile OpenType la aceeași dimensiune ca TTF. Pentru economisirea spațiului în APK, utilizați compresia prin woff2 sau încărcarea fonturilor la cerere.
Procesul de conectare a unui font personalizat în iOS constă din doi pași: adăugarea fișierului în bundle-ul proiectului și înregistrarea în Info.plist. Fișierul de font este plasat în directorul proiectului (de obicei Resources/Fonts) și inclus în target. În Info.plist se adaugă un array UIAppFonts (Fonts provided by application) cu numele fișierelor de font, inclusiv extensia.
După înregistrare, fontul este disponibil prin UIFont(name:size:) sub numele PostScript. Numele PostScript poate fi aflat prin UIFont.familyNames și UIFont.fontNames(forFamilyName:). Dacă numele este incorect, UIFont(name:size:) returnează nil. Pentru depanare, se recomandă afișarea tuturor fonturilor înregistrate pe ecran la prima lansare.
Să examinăm ciclul complet de conectare a fontului Montserrat într-un proiect iOS în Swift. Fișierul Montserrat-Regular.ttf este adăugat în proiect, specificat în Info.plist, apoi încărcat prin UIFont și aplicat la UILabel. Pentru fiecare caracter (regular, bold, italic) se adaugă un fișier separat și o intrare separată în Info.plist.
// 1. În Info.plist: UIAppFonts → "Montserrat-Regular.ttf"
// 2. Încarcă fontul în cod
guard let customFont = UIFont(name: "Montserrat-Regular", size: 16) else {
// revenire la fontul de sistem
label.font = UIFont.systemFont(ofSize: 16)
return
}
label.font = customFont
// 3. Utilizează în NSAttributedString
let attributes = [NSAttributedString.Key.font: customFont]
let attributed = NSAttributedString(string: "Text", attributes: attributes)
Gestionarea situației când fontul nu este încărcat (UIFont returnează nil) este obligatorie. În locul prăbușirii aplicației, utilizați fontul de sistem ca fallback. Acest lucru este deosebit de important pentru fonturile încărcate din rețea sau adăugate în module opționale.
Pentru fonturile descărcate la cerere se utilizează CTFontManagerRegisterGraphicsFont. Această metodă înregistrează fontul din datele din memorie (Data) și îl face disponibil pentru UIFont. După utilizare, fontul poate fi deregitrat prin CTFontManagerUnregisterGraphicsFont. Încărcarea dinamică este utilă pentru aplicațiile cu un set mare de fonturi, unde nu sunt necesare toate deodată.
Pe Android, fonturile personalizate se adaugă prin sistemul de resurse res/font. Fișierele TTF sau OTF sunt plasate în res/font/, după care se creează resurse XML Font Family pentru gruparea caracterelor. Începând cu Android 8.0 (API 26), aceasta este singura metodă recomandată. Pentru versiunile mai vechi se folosesc assets și Typeface.createFromAsset.
XML Font Family descrie corespondența dintre caracter (regular, bold, italic) și fișierul de font. În marcarea XML, atributul android:fontFamily="@font/my_font" selectează automat fișierul potrivit la setTypeface cu stilul corespunzător. Aceasta simplifică tipografia — este suficient să specificați familia în temă, iar Android va selecta singur bold la apelul setTypeface(textView, Typeface.BOLD).
Crează un fișier XML în res/font/my_font.xml, unde sunt enumerate toate fișierele de font pentru diferite caractere. Fiecare element are atributele fontStyle (normal/italic) și fontWeight (100-900). După aceea, în marcare specificați android:fontFamily="@font/my_font". La utilizarea textStyle="bold", Android va selecta automat fișierul cu fontWeight 700.
<!-- res/font/my_font.xml -->
<?xml version="1.0" encoding="utf-8"?>
<font-family xmlns:app="http://schemas.android.com/apk/res-auto">
<font
android:fontStyle="normal"
android:fontWeight="400"
app:font="@font/my_font_regular" />
<font
android:fontStyle="normal"
android:fontWeight="700"
app:font="@font/my_font_bold" />
</font-family>
La utilizarea Font Family, metoda prin resurse memorează automat fonturile în cache și selectează caracterul corect. Dacă greutatea necesară lipsește din familie, Android o sintetizează din cea mai apropiată disponibilă. Pentru un control precis asupra fontului, utilizați Typeface.create() cu specificarea explicită a fișierului.
În framework-urile cross-platform, conectarea fonturilor este unificată. Flutter utilizează pubspec.yaml pentru specificarea fonturilor: fișierele sunt plasate în folderul fonts/ al proiectului, apoi declarate în secțiunea fonts cu indicarea familiei și caracterelor. Apoi fontul se aplică prin TextStyle(fontFamily: 'Montserrat') sau în tema aplicației. Flutter suportă TTF și OTF.
React Native utilizează două abordări: nativă (prin Info.plist și res/font) sau prin bibliotecile react-native-vector-icons și @expo-google-fonts. Expo simplifică procesul — fonturile se încarcă prin expo-font: Font.loadAsync({ 'Montserrat': require('./assets/fonts/Montserrat.ttf') }). React Navigation și temele permit setarea globală a fontului.
Declararea fonturilor în pubspec.yaml și aplicarea în tema MaterialApp. Fișierele Montserrat-Regular.ttf și Montserrat-Bold.ttf sunt plasate în fonts/. După declarare, fontul este disponibil prin TextStyle în întreaga aplicație. Flutter utilizează automat fișierul bold la fontWeight: FontWeight.bold.
// pubspec.yaml
flutter:
fonts:
- family: Montserrat
fonts:
- asset: fonts/Montserrat-Regular.ttf
- asset: fonts/Montserrat-Bold.ttf
weight: 700
// Utilizare în temă
MaterialApp(
theme: ThemeData(
textTheme: TextTheme(
headlineLarge: TextStyle(
fontFamily: 'Montserrat',
fontWeight: FontWeight.bold,
fontSize: 28
)
)
)
)
Dacă Flutter nu găsește fontul la calea specificată, aplicația utilizează fontul de sistem de rezervă fără erori. Pentru depanare, activați checkConsistency în MaterialApp — acesta verifică disponibilitatea fonturilor și afișează avertismente în consolă la absențe.
Dimensiunea APK și IPA depinde direct de numărul de fonturi incluse. Un fișier TTF cântărește 50-500 KB pentru setul de caractere latine și până la 2-5 MB pentru fonturile cu suport pentru chirilică, caractere chinezești sau alte seturi extinse. Zece fonturi pot adăuga 10-20 MB la dimensiunea aplicației, ceea ce este critic pentru descărcarea mobilă.
Pentru optimizare, utilizați subsetting — eliminarea caracterelor neutilizate din fișierul de font. Instrumente precum glyphhanger, fonttools (pyftsubset) și Google Webfont Optimizer creează o versiune a fontului doar cu glifele necesare (latină + chirilică + cifre + semne de punctuație). Aceasta reduce dimensiunea cu 50-80%. Pe iOS se pot utiliza resurse on-demand pentru fonturile care nu sunt necesare la prima lansare.
Variable Font (font variabil) — este un singur fișier care conține toate caracterele: de la Thin la Black și de la Condensed la Expanded. Un font variabil poate înlocui 10-20 de fișiere separate cu greutăți diferite. Dimensiunea unui astfel de fișier este aproximativ egală cu 1-2 fișiere statice. Suport: iOS 11+, Android 10+, Flutter (prin FontVariation), React Native (prin biblioteci personalizate).
Utilizați WOFF2 pentru a reduce dimensiunea fonturilor cu 30-50%. Pe Android cu API 29 se poate utiliza WOFF2 direct. Pentru iOS este necesară convertirea WOFF2 în TTF înainte de înregistrare. Fonturile utilizate doar în onboarding sau pe anumite ecrane, încărcați-le prin resurse on-demand (iOS) sau Dynamic Feature (Android) — ele nu vor intra în APK-ul de bază.
Fonturile personalizate influențează performanța în două moduri: timpul de încărcare și memoria. La prima referire la font, sistemul citește fișierul de pe disc, parsează tabelele fontului și creează structuri interne pentru randare. Pentru un font de 1 MB, aceasta durează 20-50 ms. Memorarea în cache după prima încărcare elimină întârzierea la referirile repetate.
Memorie: fiecare font încărcat este stocat în cache-ul procesului. Fonturile de sistem sunt preîncărcate, cele personalizate — se încarcă la prima utilizare. În memorie, fontul ocupă de aproximativ 2-3 ori mai mult decât pe disc, din cauza structurilor descompuse: tabelele cmap, glyf, head, hmtx. Pentru 5 fonturi personalizate de dimensiune medie (volum total 3 MB) sunt necesari aproximativ 6-9 MB RAM.
Limitați numărul de fonturi personalizate la 2-3 familii per aplicație. Utilizați fonturi variabile pentru a înlocui mai multe caractere. Aplicați fonturi de sistem pentru elementele UI (butoane, etichete, liste) și fonturi personalizate doar pentru tipografia de accent (titluri, bannere). Memorați în cache Typeface pe Android prin Map, iar UIFont pe iOS — prin variabile statice.
object FontCache {
private val cache = mutableMapOf<String, Typeface>()
fun get(context: Context, fontId: Int): Typeface {
return cache.getOrPut(fontId.toString()) {
ResourcesCompat.getFont(context, fontId)
}
}
}
// Utilizare în RecyclerView
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
holder.textView.typeface = FontCache.get(context, R.font.montserrat_regular)
}
Încărcarea Typeface în onBindViewHolder este permisă doar în prezența cache-ului. Fără cache, fiecare apel createFromAsset creează un obiect nou și citește fișierul de pe disc. La derularea RecyclerView, aceasta provoacă întârzieri vizibile. Cache-ul rezolvă problema, deoarece fontul se încarcă o singură dată și se reutilizează.
Întrebări frecvente
OTF — alegerea optimă pentru aplicații mobile. Suportă funcții OpenType (ligaturi, glife alternative) la aceeași dimensiune ca TTF. Pentru economisirea spațiului, utilizați fonturi variabile TTX sau OTF cu subsetting. WOFF2 este potrivit doar pentru Android 10+ și nu este suportat pe iOS în aplicațiile native.
Da. Google Fonts oferă fonturi sub licența OFL (Open Font License) pentru utilizare comercială. Fonturile pot fi descărcate de pe fonts.google.com și adăugate în proiect. Android suportă Downloadable Fonts prin Google Play Services, ceea ce permite neincluderea fișierelor de font în APK, ci încărcarea lor la prima utilizare.
Cele mai frecvente cauze: fișierul nu a fost adăugat în target (iOS), nu a fost specificat în Info.plist (iOS), fișierul nu este în res/font (Android), numele PostScript incorect, fișierul este deteriorat. Pentru diagnosticare pe iOS, afișați UIFont.familyNames în consolă. Pe Android, utilizați FontLoader pentru depanarea încărcării fonturilor din assets.
Utilizați subsetting (pyftsubset) pentru eliminarea caracterelor neutilizate — reduce dimensiunea cu 50-80%. Aplicați fonturi variabile în locul a 10 fișiere separate. Utilizați compresia WOFF2 pentru Android 10+. Configurați ProGuard pentru ofuscarea căilor către fonturi. Pentru iOS, utilizați resurse on-demand.
Se recomandă limitarea la 2-3 familii (inclusiv diferite caractere). Fiecare familie adaugă 200 KB — 3 MB la dimensiunea aplicației. Fonturile de sistem nu încarcă aplicația, de aceea pentru elementele UI utilizați fonturi de sistem, iar cele personalizate păstrați pentru titluri și blocuri de accent.
Rezumat
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