Custom Font у мобилном развоју — шта је то, формати и примена

Аутор: IT Sectr Објављено: 2026-07-23 Време читања: 10 мин

Custom Font — датотека фонта (TTF, OTF, WOFF2) коју програмер додаје у мобилну апликацију да замени подразумевани системски фонт. Прилагођени фонтови се користе за стварање јединственог визуелног стила, усклађености са брендбуком и побољшање читљивости на различитим језицима. Према подацима Apple Fonts, прилагођени фонтови су подржани на свим Apple платформама, а Android пружа механизам Font Family за поједностављење учитавања. Правилно повезивање фонта критично утиче на типографију и укупан доживљај апликације.

Главно

  • Custom Font — датотека фонта додата у апликацију за замену системског писма
  • Основни формати: TTF (TrueType), OTF (OpenType), WOFF2 (Web Open Font Format)
  • iOS повезује фонтове преко Info.plist и UIFont, Android — преко res/font и Typeface
  • Сваки фонт додаје 50 KB — 5 MB величини APK или IPA
  • Варијабилни фонтови омогућавају чување свих стилова у једној датотеци

Шта је Custom Font?

Custom Font (прилагођени фонт) — датотека са писмом која није део стандардног скупа фонтова оперативног система. Програмери додају такве фонтове у пројекат за јединствену типографију у складу са брендом. Прилагођени фонтови могу бити и плаћени комерцијални фонтови и бесплатни open-source фонтови, на пример Inter, Montserrat, Roboto (прилагођена верзија).

Типични сценарији коришћења прилагођених фонтова: логотипи и наслови брендираних апликација, апликације за читање са посебним захтевима за типографију, игре са тематским фонтовима, апликације за не-латиничне језике где системски фонт не подржава потребне глифове. Према подацима Google Fonts, више од 60% апликација у топ-100 прилагођава фонтове за визуелну диференцијацију.

Зашто су потребни прилагођени фонтови

Системски фонтови (San Francisco на iOS, Roboto на Android) су оптимизовани за интерфејсе, али нису погодни за бренд типографију. Прилагођени фонт појачава препознатљивост бренда, може садржати специјалне симболе (иконични фонтови) и побољшава читљивост за специфичне аудиторије. Међутим, претерана употреба различитих фонтова погоршава UX — препоручује се не више од 2-3 фамилије по апликацији.

Формати фонтова за мобилне апликације

Мобилне платформе подржавају неколико формата фонтова. TrueType (TTF) — најраспрострањенији формат, компатибилан са свим верзијама iOS и Android. OpenType (OTF) — проширење TTF-а са подршком за лигатуре, алтернативне глифове и OpenType функције. Оба формата имају екстензије .ttf и .otf и раде идентично на мобилним платформама.

WOFF2 (Web Open Font Format 2) — компримовани формат за веб, подржан у Android од верзије 10. WOFF2 пружа компресију од 30-50% у односу на TTF. За iOS WOFF2 је подржан преко Safari-ја, али у изворним апликацијама је потребна конверзија у TTF/OTF. Variable Fonts (варијабилни фонтови) — модеран формат који чува све стилове у једној датотеци.

ФорматiOSAndroidКомпресијаКарактеристике
TTFДаДаНеСтандардни формат, широка компатибилност
OTFДаДаНеOpenType функције, лигатуре, алтернативни глифови
WOFF2Преко Safari-јаAPI 29+30-50%Компримовани, за уштеду величине APK
VariableiOS 11+API 29+ВисокаЈедна датотека за све стилове

За мобилни развој препоручује се коришћење OTF као основног формата — подржава OpenType функције при истој величини као TTF. За уштеду простора у APK користите компресију преко woff2 или учитавање фонтова на захтев.

Повезивање прилагођених фонтова у iOS

Процес повезивања прилагођеног фонта у iOS састоји се из два корака: додавање датотеке у bundle пројекта и регистрација у Info.plist. Датотека фонта се поставља у директоријум пројекта (обично Resources/Fonts) и укључује се у target. У Info.plist се додаје низ UIAppFonts (Fonts provided by application) са именима датотека фонтова, укључујући екстензију.

Након регистрације, фонт је доступан преко UIFont(name:size:) по PostScript имену. PostScript име се може сазнати преко UIFont.familyNames и UIFont.fontNames(forFamilyName:). Ако је име нетачно, UIFont(name:size:) враћа nil. За отклањање грешака препоручује се приказ свих регистрованих фонтова на екрану при првом покретању.

Пример повезивања

Размотримо комплетан циклус повезивања фонта Montserrat у iOS пројекту на Swift-у. Датотека Montserrat-Regular.ttf се додаје у пројекат, наводи у Info.plist, затим учитава преко UIFont и примењује на UILabel. За сваки стил (regular, bold, italic) додаје се посебна датотека и посебан унос у Info.plist.

swift
// 1. У Info.plist: UIAppFonts → "Montserrat-Regular.ttf"
// 2. Учитај фонт у коду
guard let customFont = UIFont(name: "Montserrat-Regular", size: 16) else {
    // повратак на системски фонт
    label.font = UIFont.systemFont(ofSize: 16)
    return
}
label.font = customFont
// 3. Користи у NSAttributedString
let attributes = [NSAttributedString.Key.font: customFont]
let attributed = NSAttributedString(string: "Text", attributes: attributes)

Обрада ситуације када фонт није учитан (UIFont враћа nil) је обавезна. Уместо пада апликације користите системски фонт као fallback. Ово је посебно важно за фонтове који се учитавају из мреже или додају у опционе модуле.

Динамичко учитавање преко CTFontManager

За фонтове који се преузимају на захтев користи се CTFontManagerRegisterGraphicsFont. Овај метод региструје фонт из података у меморији (Data) и чини га доступним за UIFont. Након употребе, фонт се може одрегистровати преко CTFontManagerUnregisterGraphicsFont. Динамичко учитавање је корисно за апликације са великим скупом фонтова, где нису сви потребни одједном.

Повезивање прилагођених фонтова у Android

На Android-у се прилагођени фонтови додају кроз систем ресурса res/font. Датотеке TTF или OTF се постављају у res/font/, након чега се креирају XML ресурси Font Family за груписање стилова. Почев од Android 8.0 (API 26), ово је једини препоручени начин. За старије верзије користе се assets и Typeface.createFromAsset.

XML Font Family описује подударање између стила (regular, bold, italic) и датотеке фонта. У XML ознаци атрибут android:fontFamily="@font/my_font" аутоматски бира одговарајућу датотеку при setTypeface са одговарајућим стилом. Ово поједностављује типографију — довољно је навести фамилију у теми, а Android ће сам изабрати bold при позиву setTypeface(textView, Typeface.BOLD).

Креирање Font Family

Креирајте XML датотеку у res/font/my_font.xml, где су наведене све датотеке фонта за различите стилове. Сваки елемент има атрибуте fontStyle (normal/italic) и fontWeight (100-900). Након тога у ознаци наведите android:fontFamily="@font/my_font". При коришћењу textStyle="bold", Android ће аутоматски изабрати датотеку са fontWeight 700.

xml
<!-- 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>

При коришћењу Font Family, ресурсни начин аутоматски кешира фонтове и бира правилан стил. Ако потребна тежина недостаје у фамилији, Android је синтетише из најближе доступне. За прецизну контролу над фонтом користите Typeface.create() са експлицитним навођењем датотеке.

Повезивање у Flutter и React Native

У вишеплатформским оквирима повезивање фонтова је унификовано. Flutter користи pubspec.yaml за навођење фонтова: датотеке се постављају у фасциклу fonts/ пројекта, затим се декларишу у секцији fonts са навођењем фамилије и стилова. Затим се фонт примењује кроз TextStyle(fontFamily: 'Montserrat') или у теми апликације. Flutter подржава TTF и OTF.

React Native користи два приступа: изворни (преко Info.plist и res/font) или кроз библиотеке react-native-vector-icons и @expo-google-fonts. Expo поједностављује процес — фонтови се учитавају кроз expo-font: Font.loadAsync({ 'Montserrat': require('./assets/fonts/Montserrat.ttf') }). React Navigation и теме омогућавају глобално постављање фонта.

Пример у Flutter-у

Декларација фонтова у pubspec.yaml и примена у теми MaterialApp. Датотеке Montserrat-Regular.ttf и Montserrat-Bold.ttf се постављају у fonts/. Након декларације, фонт је доступан кроз TextStyle у целој апликацији. Flutter аутоматски користи bold датотеку при fontWeight: FontWeight.bold.

dart
// pubspec.yaml
flutter:
  fonts:
    - family: Montserrat
      fonts:
        - asset: fonts/Montserrat-Regular.ttf
        - asset: fonts/Montserrat-Bold.ttf
          weight: 700
// Употреба у теми
MaterialApp(
  theme: ThemeData(
    textTheme: TextTheme(
      headlineLarge: TextStyle(
        fontFamily: 'Montserrat',
        fontWeight: FontWeight.bold,
        fontSize: 28
      )
    )
  )
)

Ако Flutter не пронађе фонт на наведеној путањи, апликација користи системски резервни фонт без грешака. За отклањање грешака укључите checkConsistency у MaterialApp — он проверава доступност фонтова и приказује упозорења у конзоли при недостатку.

Оптимизација величине фонтова

Величина APK и IPA директно зависи од броја укључених фонтова. Једна TTF датотека тежи 50-500 KB за латинични скуп знакова и до 2-5 MB за фонтове са подршком за ћирилицу, кинеске знакове или друге проширене скупове. Десет фонтова може додати 10-20 MB величини апликације, што је критично за мобилно преузимање.

За оптимизацију користите subsetting — уклањање некоришћених знакова из датотеке фонта. Алати попут glyphhanger, fonttools (pyftsubset) и Google Webfont Optimizer креирају верзију фонта само са потребним глифовима (латиница + ћирилица + бројеви + интерпункцијски знаци). Ово смањује величину за 50-80%. На iOS-у се могу користити on-demand ресурси за фонтове који нису потребни при првом покретању.

Варијабилни фонтови

Variable Font (варијабилни фонт) — једна датотека која садржи све стилове: од Thin до Black и од Condensed до Expanded. Један варијабилни фонт може заменити 10-20 одвојених датотека са различитим тежинама. Величина такве датотеке је приближно једнака 1-2 статичке датотеке. Подршка: iOS 11+, Android 10+, Flutter (кроз FontVariation), React Native (кроз прилагођене библиотеке).

Компресија и учитавање на захтев

Користите WOFF2 за смањење величине фонтова за 30-50%. На Android-у са API 29 можете користити WOFF2 директно. За iOS је потребно конвертовати WOFF2 у TTF пре регистрације. Фонтове који се користе само у онбордингу или на одређеним екранима учитавајте кроз on-demand ресурсе (iOS) или Dynamic Feature (Android) — они неће ући у основни APK.

Перформансе и најбоље праксе

Прилагођени фонтови утичу на перформансе на два начина: време учитавања и меморија. При првом позивању фонта, систем чита датотеку са диска, парсира табеле фонта и ствара унутрашње структуре за рендеровање. За фонт величине 1 MB ово траје 20-50 ms. Кеширање након првог учитавања уклања кашњење при поновљеним позивањима.

Меморија: сваки учитани фонт се чува у кешу процеса. Системски фонтови су претходно учитани, прилагођени — учитавају се при првој употреби. У меморији фонт заузима приближно 2-3 пута више него на диску, због рашчлањених структура: табела cmap, glyf, head, hmtx. За 5 прилагођених фонтова средње величине (укупна запремина 3 MB) потребно је око 6-9 MB RAM-а.

Препоруке

Ограничите број прилагођених фонтова на 2-3 фамилије по апликацији. Користите варијабилне фонтове за замену више стилова. Примењујте системске фонтове за UI елементе (дугмад, натписи, листе), а прилагођене само за акцентну типографију (наслови, банери). Кеширајте Typeface на Android-у кроз Map, а UIFont на iOS-у — кроз статичке променљиве.

kotlin
object FontCache {
    private val cache = mutableMapOf<String, Typeface>()
    fun get(context: Context, fontId: Int): Typeface {
        return cache.getOrPut(fontId.toString()) {
            ResourcesCompat.getFont(context, fontId)
        }
    }
}
// Употреба у RecyclerView
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
    holder.textView.typeface = FontCache.get(context, R.font.montserrat_regular)
}

Учитавање Typeface у onBindViewHolder је дозвољено само уз постојање кеша. Без кеша, сваки позив createFromAsset ствара нови објекат и чита датотеку са диска. При скроловању RecyclerView-а ово изазива приметна застоја. Кеш решава проблем, јер се фонт учитава једном и поново користи.

Често постављана питања

Који формат фонта је најбољи за мобилне апликације?

OTF — оптималан избор за мобилне апликације. Подржава OpenType функције (лигатуре, алтернативне глифове) при истој величини као TTF. За уштеду простора користите варијабилне фонтове TTX или OTF са subsetting-ом. WOFF2 је погодан само за Android 10+ и није подржан на iOS-у у изворним апликацијама.

Могу ли се користити Google Fonts у мобилним апликацијама?

Да. Google Fonts пружа фонтове под OFL (Open Font License) лиценцом за комерцијалну употребу. Фонтови се могу преузети са fonts.google.com и додати у пројекат. Android подржава Downloadable Fonts кроз Google Play Services, што омогућава да се датотеке фонтова не укључују у APK, већ да се учитавају при првој употреби.

Зашто се прилагођени фонт не приказује?

Најчешћи разлози: датотека није додата у target (iOS), није наведена у Info.plist (iOS), датотека није у res/font (Android), наведено је нетачно PostScript име, датотека је оштећена. За дијагностику на iOS-у прикажите UIFont.familyNames у конзоли. На Android-у користите FontLoader за отклањање грешака при учитавању фонтова из assets-а.

Како смањити величину фонта у APK-у?

Користите subsetting (pyftsubset) за уклањање некоришћених знакова — смањује величину за 50-80%. Примењујте варијабилне фонтове уместо 10 одвојених датотека. Користите WOFF2 компресију за Android 10+. Подесите ProGuard за обфускацију путања до фонтова. За iOS користите on-demand ресурсе.

Колико прилагођених фонтова се може користити у апликацији?

Препоручује се ограничити на 2-3 фамилије (укључујући различите стилове). Свака фамилија додаје 200 KB — 3 MB величини апликације. Системски фонтови не оптерећују апликацију, зато за UI елементе користите системске, а прилагођене оставите за наслове и акцентне блокове.

Закључак

  • Custom Font — датотека фонта (TTF, OTF, WOFF2) додата у апликацију за бренд типографију
  • iOS: датотека у bundle + UIAppFonts у Info.plist + UIFont(name:size:)
  • Android: датотека у res/font + XML Font Family + Typeface или android:fontFamily
  • Flutter: декларација у pubspec.yaml + TextStyle(fontFamily:)
  • Оптимизација: subsetting смањује величину фонта за 50-80% уз задржавање потребних знакова
  • Варијабилни фонтови замењују 10-20 статичких датотека једном датотеком са свим стиловима
  • Кеширајте фонтове при учитавању — једна инстанца по сесији апликације

Развићемо мобилну апликацију под кључ

IT Sectr креира iOS и Android апликације за стартапе и предузећа од 2017. године. Саветоваћемо вас и предложити најбоље решење.

Разговарајте о пројекту

Прочитајте такође