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 КБ — 5 МБ к размеру 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Через SafariAPI 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. In Info.plist: UIAppFonts → "Montserrat-Regular.ttf"
// 2. Load font in code
guard let customFont = UIFont(name: "Montserrat-Regular", size: 16) else {
    // fallback to system font
    label.font = UIFont.systemFont(ofSize: 16)
    return
}
label.font = customFont
// 3. Use in 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
// Usage in theme
MaterialApp(
  theme: ThemeData(
    textTheme: TextTheme(
      headlineLarge: TextStyle(
        fontFamily: 'Montserrat',
        fontWeight: FontWeight.bold,
        fontSize: 28
      )
    )
  )
)

Если Flutter не находит шрифт по указанному пути, приложение использует системный fallback-шрифт без ошибок. Для отладки включите checkConsistency в MaterialApp — он проверяет наличие шрифтов и выводит предупреждения в консоль при отсутствии.

Оптимизация размера шрифтов

Размер APK и IPA напрямую зависит от количества включённых шрифтов. Один файл TTF весит 50–500 КБ для латинского набора символов и до 2–5 МБ для шрифтов с поддержкой кириллицы, китайских иероглифов или других расширенных наборов. Десять шрифтов могут добавить 10–20 МБ к размеру приложения, что критично для мобильной загрузки.

Для оптимизации используйте 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.

Производительность и best practices

Кастомные шрифты влияют на производительность двумя способами: время загрузки и память. При первом обращении к шрифту система читает файл с диска, парсит таблицы шрифта и создаёт внутренние структуры для рендеринга. Для шрифта размером 1 МБ это занимает 20–50 мс. Кэширование после первой загрузки устраняет задержку при повторных обращениях.

Память: каждый загруженный шрифт хранится в кэше процесса. Системные шрифты предзагружены, кастомные — загружаются при первом использовании. В памяти шрифт занимает примерно в 2–3 раза больше, чем на диске, из-за разобранных структур: таблиц cmap, glyf, head, hmtx. Для 5 кастомных шрифтов среднего размера (общий объём 3 МБ) потребуется около 6–9 МБ 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)
        }
    }
}
// Usage in 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 КБ — 3 МБ к размеру приложения. Системные шрифты не нагружают приложение, поэтому для 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 года. Мы проконсультируем вас и предложим наилучшее решение.

Обсудить проект

Читайте также