Custom Font — je soubor písma (TTF, OTF, WOFF2), který vývojář přidává do mobilní aplikace pro nahrazení výchozího systémového písma. Vlastní písma se používají pro vytvoření jedinečného vizuálního stylu, souladu s brandbookem a zlepšení čitelnosti v různých jazycích. Podle údajů Apple Fonts jsou vlastní písma podporována na všech platformách Apple a Android poskytuje mechanismus Font Family pro zjednodušení načítání. Správné připojení písma kriticky ovlivňuje typografii a celkový dojem z aplikace.
Hlavní body
Custom Font (vlastní písmo) — je soubor s řezem, který není součástí standardní sady písem operačního systému. Vývojáři přidávají taková písma do projektu pro jedinečnou typografii odpovídající značce. Vlastní písma mohou být jak placená komerční písma, tak bezplatná open-source písma, například Inter, Montserrat, Roboto (vlastní verze).
Typické scénáře použití vlastních písem: loga a nadpisy značkových aplikací, čtečky se speciálními typografickými požadavky, hry s tematickými písmy, aplikace pro nelatinské jazyky, kde systémové písmo nepodporuje potřebné glyfy. Podle údajů Google Fonts přizpůsobuje písma pro vizuální diferenciaci více než 60 % aplikací v top 100.
Systémová písma (San Francisco na iOS, Roboto na Android) jsou optimalizována pro rozhraní, ale nehodí se pro typografii značky. Vlastní písmo posiluje rozpoznatelnost značky, může obsahovat speciální symboly (ikonová písma) a zlepšuje čitelnost pro specifické publikum. Nadměrné používání různých písem však zhoršuje UX — doporučuje se nejvýše 2-3 rodiny na aplikaci.
Mobilní platformy podporují několik formátů písem. TrueType (TTF) — nejrozšířenější formát, kompatibilní se všemi verzemi iOS a Android. OpenType (OTF) — rozšíření TTF s podporou ligatur, alternativních glyfů a funkcí OpenType. Oba formáty mají přípony .ttf a .otf a fungují na mobilních platformách identicky.
WOFF2 (Web Open Font Format 2) — komprimovaný formát pro web, podporovaný v Android od verze 10. WOFF2 poskytuje kompresi 30-50 % oproti TTF. Pro iOS je WOFF2 podporován přes Safari, ale v nativních aplikacích je vyžadována konverze do TTF/OTF. Variable Fonts (variabilní písma) — moderní formát ukládající všechny řezy v jednom souboru.
| Formát | iOS | Android | Komprese | Vlastnosti |
|---|---|---|---|---|
| TTF | Ano | Ano | Ne | Standardní formát, široká kompatibilita |
| OTF | Ano | Ano | Ne | Funkce OpenType, ligatury, alternativní glyfy |
| WOFF2 | Přes Safari | API 29+ | 30-50 % | Komprimovaný, pro úsporu velikosti APK |
| Variable | iOS 11+ | API 29+ | Vysoká | Jeden soubor pro všechny řezy |
Pro mobilní vývoj se doporučuje používat OTF jako hlavní formát — podporuje funkce OpenType při stejné velikosti jako TTF. Pro úsporu místa v APK použijte kompresi přes woff2 nebo načítání písem na vyžádání.
Proces připojení vlastního písma v iOS se skládá ze dvou kroků: přidání souboru do bundle projektu a registrace v Info.plist. Soubor písma se umístí do adresáře projektu (obvykle Resources/Fonts) a zahrne se do targetu. Do Info.plist se přidá pole UIAppFonts (Fonts provided by application) s názvy souborů písem včetně přípony.
Po registraci je písmo dostupné přes UIFont(name:size:) pod jménem PostScript. Jméno PostScript lze zjistit přes UIFont.familyNames a UIFont.fontNames(forFamilyName:). Pokud je jméno nesprávné, UIFont(name:size:) vrací nil. Pro ladění se doporučuje zobrazit všechna registrovaná písma na obrazovce při prvním spuštění.
Podívejme se na úplný cyklus připojení písma Montserrat v iOS projektu ve Swift. Soubor Montserrat-Regular.ttf se přidá do projektu, uvede se v Info.plist, poté se načte přes UIFont a aplikuje se na UILabel. Pro každý řez (regular, bold, italic) se přidá samostatný soubor a samostatný záznam v Info.plist.
// 1. V Info.plist: UIAppFonts → "Montserrat-Regular.ttf"
// 2. Načtení písma v kódu
guard let customFont = UIFont(name: "Montserrat-Regular", size: 16) else {
// záložní systémové písmo
label.font = UIFont.systemFont(ofSize: 16)
return
}
label.font = customFont
// 3. Použití v NSAttributedString
let attributes = [NSAttributedString.Key.font: customFont]
let attributed = NSAttributedString(string: "Text", attributes: attributes)
Zpracování situace, kdy písmo není načteno (UIFont vrací nil), je povinné. Místo pádu aplikace použijte systémové písmo jako fallback. To je důležité zejména pro písma načítaná ze sítě nebo přidávaná do volitelných modulů.
Pro písma stahovaná na vyžádání se používá CTFontManagerRegisterGraphicsFont. Tato metoda registruje písmo z dat v paměti (Data) a zpřístupňuje jej pro UIFont. Po použití lze písmo odregistrovat přes CTFontManagerUnregisterGraphicsFont. Dynamické načítání je užitečné pro aplikace s velkou sadou písem, kde nejsou všechna potřeba najednou.
V Android se vlastní písma přidávají přes systém prostředků res/font. Soubory TTF nebo OTF se umístí do res/font/, poté se vytvoří XML prostředky Font Family pro seskupení řezů. Od Android 8.0 (API 26) je to jediný doporučený způsob. Pro starší verze se používají assets a Typeface.createFromAsset.
XML Font Family popisuje shodu mezi řezem (regular, bold, italic) a souborem písma. V XML značce atribut android:fontFamily="@font/my_font" automaticky vybírá odpovídající soubor při setTypeface s příslušným stylem. To zjednodušuje typografii — stačí uvést rodinu v tématu a Android sám vybere bold při volání setTypeface(textView, Typeface.BOLD).
Vytvořte XML soubor v res/font/my_font.xml, kde jsou uvedeny všechny soubory písma pro různé řezy. Každý prvek má atributy fontStyle (normal/italic) a fontWeight (100-900). Poté v značce uveďte android:fontFamily="@font/my_font". Při použití textStyle="bold" Android automaticky vybere soubor s 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>
Při použití Font Family způsob prostředků automaticky ukládá písma do mezipaměti a vybírá správný řez. Pokud požadovaná váha v rodině chybí, Android ji syntetizuje z nejbližší dostupné. Pro přesnou kontrolu nad písmem použijte Typeface.create() s explicitním uvedením souboru.
V multiplatformních frameworkch je připojení písem sjednoceno. Flutter používá pubspec.yaml pro specifikaci písem: soubory se umístí do složky fonts/ projektu, poté se deklarují v sekci fonts s uvedením rodiny a řezů. Poté se písmo aplikuje přes TextStyle(fontFamily: 'Montserrat') nebo v tématu aplikace. Flutter podporuje TTF a OTF.
React Native používá dva přístupy: nativní (přes Info.plist a res/font) nebo přes knihovny react-native-vector-icons a @expo-google-fonts. Expo proces zjednodušuje — písma se načítají přes expo-font: Font.loadAsync({ 'Montserrat': require('./assets/fonts/Montserrat.ttf') }). React Navigation a témata umožňují globální nastavení písma.
Deklarace písem v pubspec.yaml a aplikace v tématu MaterialApp. Soubory Montserrat-Regular.ttf a Montserrat-Bold.ttf se umístí do fonts/. Po deklaraci je písmo dostupné přes TextStyle v celé aplikaci. Flutter automaticky používá bold soubor při fontWeight: FontWeight.bold.
// pubspec.yaml
flutter:
fonts:
- family: Montserrat
fonts:
- asset: fonts/Montserrat-Regular.ttf
- asset: fonts/Montserrat-Bold.ttf
weight: 700
// Použití v tématu
MaterialApp(
theme: ThemeData(
textTheme: TextTheme(
headlineLarge: TextStyle(
fontFamily: 'Montserrat',
fontWeight: FontWeight.bold,
fontSize: 28
)
)
)
)
Pokud Flutter nenajde písmo na uvedené cestě, aplikace použije systémové záložní písmo bez chyb. Pro ladění zapněte checkConsistency v MaterialApp — kontroluje dostupnost písem a zobrazuje varování v konzoli při absenci.
Velikost APK a IPA přímo závisí na počtu zahrnutých písem. Jeden soubor TTF váží 50-500 KB pro latinskou sadu znaků a až 2-5 MB pro písma s podporou cyrilice, čínských znaků nebo jiných rozšířených sad. Deset písem může přidat 10-20 MB k velikosti aplikace, což je kritické pro mobilní stahování.
Pro optimalizaci použijte subsetting — odstranění nepoužívaných znaků ze souboru písma. Nástroje jako glyphhanger, fonttools (pyftsubset) a Google Webfont Optimizer vytvoří verzi písma pouze s potřebnými glyfy (latinka + cyrilice + číslice + interpunkční znaménka). To zmenší velikost o 50-80 %. Na iOS lze použít on-demand prostředky pro písma, která nejsou potřeba při prvním spuštění.
Variable Font (variabilní písmo) — jeden soubor obsahující všechny řezy: od Thin po Black a od Condensed po Expanded. Jedno variabilní písmo může nahradit 10-20 samostatných souborů s různými váhami. Velikost takového souboru je přibližně rovna 1-2 statickým souborům. Podpora: iOS 11+, Android 10+, Flutter (přes FontVariation), React Native (přes vlastní knihovny).
Použijte WOFF2 pro zmenšení velikosti písem o 30-50 %. Na Android s API 29 lze WOFF2 použít přímo. Pro iOS je třeba před registrací převést WOFF2 do TTF. Písma používaná pouze v onboardingu nebo na určitých obrazovkách načítejte přes on-demand prostředky (iOS) nebo Dynamic Feature (Android) — nebudou součástí základního APK.
Vlastní písma ovlivňují výkon dvěma způsoby: dobou načítání a pamětí. Při prvním odkazu na písmo systém přečte soubor z disku, parsuje tabulky písma a vytvoří interní struktury pro vykreslování. Pro písmo o velikosti 1 MB to trvá 20-50 ms. Ukládání do mezipaměti po prvním načtení odstraňuje zpoždění při opakovaných odkazech.
Paměť: každé načtené písmo je uloženo v mezipaměti procesu. Systémová písma jsou přednačtena, vlastní se načítají při prvním použití. V paměti zabírá písmo přibližně 2-3krát více místa než na disku kvůli rozloženým strukturám: tabulkám cmap, glyf, head, hmtx. Pro 5 vlastních písem střední velikosti (celkový objem 3 MB) je potřeba asi 6-9 MB RAM.
Omezte počet vlastních písem na 2-3 rodiny na aplikaci. Používejte variabilní písma pro nahrazení několika řezů. Aplikujte systémová písma pro prvky UI (tlačítka, popisky, seznamy) a vlastní pouze pro akcentní typografii (nadpisy, bannery). Ukládejte do mezipaměti Typeface na Android přes Map a UIFont na iOS přes statické proměnné.
object FontCache {
private val cache = mutableMapOf<String, Typeface>()
fun get(context: Context, fontId: Int): Typeface {
return cache.getOrPut(fontId.toString()) {
ResourcesCompat.getFont(context, fontId)
}
}
}
// Použití v RecyclerView
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
holder.textView.typeface = FontCache.get(context, R.font.montserrat_regular)
}
Načítání Typeface v onBindViewHolder je povoleno pouze při existenci mezipaměti. Bez mezipaměti každé volání createFromAsset vytváří nový objekt a čte soubor z disku. Při rolování RecyclerView to způsobuje znatelné prodlevy. Mezipaměť problém řeší, protože písmo se načte jednou a znovu používá.
Často kladené otázky
OTF — optimální volba pro mobilní aplikace. Podporuje funkce OpenType (ligatury, alternativní glyfy) při stejné velikosti jako TTF. Pro úsporu místa použijte variabilní písma TTX nebo OTF s subsettingem. WOFF2 je vhodný pouze pro Android 10+ a není podporován na iOS v nativních aplikacích.
Ano. Google Fonts poskytuje písma pod licencí OFL (Open Font License) pro komerční použití. Písma lze stáhnout z fonts.google.com a přidat do projektu. Android podporuje Downloadable Fonts přes Google Play Services, což umožňuje nezahrnovat soubory písem do APK, ale načítat je při prvním použití.
Nejčastější příčiny: soubor není přidán do targetu (iOS), není uveden v Info.plist (iOS), soubor není v res/font (Android), uvedeno nesprávné jméno PostScript, poškozený soubor. Pro diagnostiku na iOS zobrazte UIFont.familyNames v konzoli. Na Android použijte FontLoader pro ladění načítání písem z assets.
Použijte subsetting (pyftsubset) pro odstranění nepoužívaných znaků — zmenší velikost o 50-80 %. Aplikujte variabilní písma místo 10 samostatných souborů. Použijte kompresi WOFF2 pro Android 10+. Nakonfigurujte ProGuard pro obfuskaci cest k písmům. Pro iOS použijte on-demand prostředky.
Doporučuje se omezit na 2-3 rodiny (včetně různých řezů). Každá rodina přidává 200 KB — 3 MB k velikosti aplikace. Systémová písma aplikaci nezatěžují, proto pro prvky UI používejte systémová a vlastní ponechte pro nadpisy a akcentní bloky.
Shrnutí
Vyvineme mobilní aplikaci na klíč
IT Sectr vytváří aplikace pro iOS a Android pro startupy a podniky od roku 2017. Poradíme vám a navrhneme nejlepší řešení.
Přečtěte si také