Dynamic Type на iOS: как адаптировать шрифт к настройкам пользователя

Dynamic Type на iOS: как адаптировать шрифт к настройкам пользователя
Dynamic Type — системный механизм iOS, который автоматически изменяет размер текста в приложении в соответствии с настройками пользователя. Чтобы интерфейс действительно адаптировался, нужно применять системные текстовые стили или корректно масштабировать собственный шрифт, проверять длинные строки и учитывать специальные возможности доступности.
Что такое Dynamic Type и зачем он нужен
Dynamic Type позволяет пользователю выбрать комфортный размер текста на уровне системы, не меняя настройки каждого приложения отдельно. Пользователь может увеличить или уменьшить шрифт в параметрах экрана и размера текста, а для некоторых категорий доступности доступны ещё более крупные значения. Приложение получает эту настройку и перестраивает текстовые элементы.
Главная цель Dynamic Type — сохранить читаемость без потери содержания и управления. Если интерфейс рассчитан только на стандартный размер, пользователи с ослабленным зрением сталкиваются с обрезанными заголовками, наложением элементов и слишком маленькими подписями. Адаптивная типографика делает приложение устойчивым к разным сценариям использования.
Важно отличать Dynamic Type от простого увеличения всех размеров в макете. Системный подход учитывает назначение текста: заголовок, основной текст, подпись, кнопка или вспомогательная информация масштабируются относительно своих текстовых стилей. Поэтому иерархия сохраняется, а интерфейс остаётся визуально цельным.
Какие текстовые стили используются в iOS
Вместо жёстко заданного кегля приложение может использовать именованные стили iOS: largeTitle, title1, title2, title3, headline, body, callout, subheadline, footnote и caption1 с caption2. Каждый стиль описывает роль текста, а не только его размер. Это упрощает масштабирование и помогает поддерживать понятную визуальную иерархию.
- largeTitle и title1 подходят для крупных заголовков экранов.
- headline используют для заметных названий секций или важных элементов.
- body предназначен для основного содержимого и длинных абзацев.
- callout и subheadline подходят для вторичного текста средней значимости.
- footnote и caption используют для примечаний, подписей и метаданных.
Такой выбор лучше, чем набор произвольных значений вроде 14, 16 и 24 пункта. Системный текстовый стиль связывает оформление с назначением элемента. Если в будущем меняются рекомендации платформы или пользователь выбирает крупный шрифт, приложение получает более предсказуемое поведение без ручной настройки каждого экрана.
Настройка Dynamic Type в UIKit
Используйте предпочтительный системный шрифт
В UIKit для получения шрифта по текстовому стилю применяется UIFont.preferredFont(forTextStyle:). Например, для обычного текста выбирают стиль body, для заголовка — title2 или headline. Такой шрифт уже связан с текущей категорией размера пользователя. Важно не заменять его последующим присваиванием фиксированного UIFont, иначе связь с настройками будет потеряна.
Включите автоматическое обновление размеров
Для UILabel, UITextView и UITextField необходимо разрешить автоматическое изменение шрифта при смене категории Dynamic Type. В UIKit для этого используется свойство adjustsFontForContentSizeCategory. Оно особенно важно, если пользователь изменяет размер текста, пока приложение открыто или возвращается в него после перехода в системные настройки.
Одного изменения кегля недостаточно для сложных экранов. UILabel должен поддерживать нужное количество строк, а контейнеры — корректно перераспределять свободное место. Для вертикальных форм и карточек обычно надёжнее использовать Auto Layout с достаточными приоритетами, чем рассчитывать координаты вручную.
Поддержка Dynamic Type в SwiftUI
В SwiftUI системные стили задаются через модификатор font, например .font(.body), .font(.headline) или .font(.title2). Окружение доступности передаёт представлениям текущую категорию размера, поэтому стандартные текстовые стили масштабируются автоматически. При этом контейнеры должны позволять содержимому занимать больше вертикального пространства.
Для собственных числовых параметров в SwiftUI применяют ScaledMetric. Он полезен, когда рядом с текстом нужно пропорционально изменить отступ, радиус или размер декоративного элемента. Однако ScaledMetric не должен превращаться в замену системным текстовым стилям: сначала настройте шрифт через семантический стиль, а затем масштабируйте только те размеры, которые действительно связаны с текстом.
Как адаптировать собственный шрифт к настройкам пользователя
Брендовый или авторский шрифт можно использовать вместе с Dynamic Type, но его нельзя просто назначить фиксированным размером. В UIKit для этого предназначен UIFontMetrics: объект связывает исходный размер шрифта с выбранным текстовым стилем и возвращает масштабированную версию. Для основного текста обычно выбирают metrics, соответствующие body, а для заголовков — отдельный стиль.
Пример сценария: у приложения есть фирменный гротеск с базовым размером 17 пунктов. Вместо того чтобы всегда задавать этот размер, разработчик передаёт шрифт в UIFontMetrics для стиля body. При стандартной категории текст выглядит привычно, а при увеличении размера получает системное масштабирование. Межстрочный интервал и ширину блока нужно проверить отдельно, потому что у разных гарнитур меняется фактическая высота строки.
- Определите роль шрифта: основной текст, заголовок, подпись или кнопка.
- Выберите соответствующий системный текстовый стиль.
- Масштабируйте базовый размер через UIFontMetrics или аналогичный механизм.
- Проверьте кириллицу, цифры, знаки пунктуации и специальные символы.
- Убедитесь, что начертания regular, medium и bold визуально сохраняют контраст.
Пошаговый процесс адаптации интерфейса
Шаг 1. Составьте карту текстовых ролей
Сначала выпишите все текстовые элементы экрана и назначьте каждому смысловую роль. Название экрана может быть title1, заголовок карточки — headline, описание — body, а дата обновления — footnote. Если разные элементы имеют одинаковое назначение, используйте один стиль. Такая карта снижает число исключений и делает дизайн-систему последовательной.
Шаг 2. Уберите фиксированные размеры текста
Найдите в проекте ручные размеры шрифта и решите, какие из них действительно необходимы. Фиксированный кегль может быть оправдан для технического интерфейса или декоративного логотипа, но обычный текст, меню, формы и сообщения лучше перевести на Dynamic Type. Проверяйте не только основной экран, но и модальные окна, ошибки валидации и пустые состояния.
Шаг 3. Сделайте компоновку гибкой
Увеличенный текст часто требует не только большей высоты, но и другой композиции. Горизонтальная строка с заголовком и кнопкой может превратиться в вертикальный блок, а короткая подпись — занять две или три строки. Используйте UIStackView, гибкие ограничения Auto Layout или адаптивные контейнеры SwiftUI вместо жёстких координат и фиксированной высоты ячеек.
Шаг 4. Проверьте кнопки, списки и формы
Кнопка должна оставаться полностью читаемой даже при крупном тексте. Не обрезайте название ради сохранения одной строки: лучше разрешить перенос, увеличить высоту или изменить расположение элементов. В формах проверяйте подсказки, сообщения об ошибках, значения по умолчанию и клавиатурные сценарии, поскольку именно вспомогательный текст часто забывают адаптировать.
Шаг 5. Протестируйте категории доступности
Проверяйте интерфейс минимум в стандартной, увеличенной и одной из самых крупных категорий текста. Оцените заголовки, длинные абзацы, кнопки, таблицы, вкладки, уведомления и элементы навигации. Отдельно включите жирный текст, если приложение должно поддерживать эту системную настройку. Тестируйте реальные строки на русском языке, а не только короткие английские заглушки.
Практические примеры для разных экранов
На экране статьи заголовок можно связать со стилем title1, подзаголовок — с headline, а основной материал — с body. При увеличении шрифта текст должен последовательно уходить вниз, не перекрывая изображение и панель действий. Для изображения задайте независимые ограничения, чтобы рост текста не обрезал содержимое статьи.
В каталоге шрифтов карточка может содержать название гарнитуры, краткое описание и кнопку действия. Название не обязательно всегда оставлять в одну строку: при крупном тексте безопаснее разрешить перенос и увеличить высоту карточки. Если рядом находится образец шрифта, его масштабирование должно быть согласовано с ролью элемента, а не привязано к случайному числу пунктов.
В настройках приложения длинные названия пунктов и пояснения особенно чувствительны к размеру текста. Переключатель или стрелка не должны сжимать текст до нечитаемой ширины. На узком экране полезно перейти от горизонтальной пары «текст плюс контроль» к компоновке, где подпись занимает доступное пространство, а интерактивный элемент сохраняет собственный размер.
Что должно масштабироваться, а что — нет
Текстовые элементы обычно масштабируются вместе с Dynamic Type, а декоративные изображения, логотипы и иконки не обязаны увеличиваться в той же пропорции. Исключение — элементы, размер которых напрямую влияет на понимание или нажатие. Например, маленькая иконка рядом с увеличенным текстом может потребовать корректировки отступа, но не должна автоматически становиться огромной.
Не уменьшайте шрифт, чтобы вместить больше данных в таблицу или сложную панель. Если контент перестаёт помещаться, сначала пересмотрите структуру: сократите второстепенные подписи, перенесите детали на отдельный экран или разрешите вертикальную прокрутку. Доступность важнее сохранения первоначальной плотности макета.
Частые ошибки при внедрении Dynamic Type
- Задавать всем элементам фиксированный кегль и считать интерфейс адаптивным только из-за изменения масштаба экрана.
- Использовать системный стиль, а затем заменять его шрифтом с постоянным размером.
- Ограничивать UILabel одной строкой без проверки длинных заголовков и локализации.
- Задавать фиксированную высоту ячейки, которая не увеличивается вместе с текстом.
- Проверять только стандартный размер и не открывать категории доступности.
- Масштабировать текст, но забывать о межстрочном интервале, отступах и порядке блоков.
- Считать, что поддержка Dynamic Type автоматически решает проблемы контраста и удобства нажатия.
Самая распространённая ошибка — формальная поддержка API без проверки компоновки. Приложение действительно получает крупный шрифт, но заголовок обрезается, кнопка исчезает за границами, а содержание карточки перекрывает соседний элемент. Поэтому адаптация типографики должна входить в визуальное и функциональное тестирование каждого экрана.
Чеклист проверки адаптивного шрифта
- Назначьте каждому текстовому элементу семантическую роль и системный стиль.
- Подключите автоматическое обновление размера в UIKit или стандартные стили SwiftUI.
- Настройте масштабирование собственного шрифта через UIFontMetrics либо эквивалентный механизм.
- Проверьте переносы, высоту строк, отступы и порядок блоков.
- Откройте экран в нескольких категориях размера текста.
- Протестируйте длинные русские строки, числа, даты и сообщения об ошибках.
- Проверьте кнопки, поля ввода, списки, модальные окна и пустые состояния.
- Убедитесь, что после увеличения текста пользователь не теряет содержание и управление.
Часто задаваемые вопросы о Dynamic Type на iOS
Работает ли Dynamic Type автоматически в любом приложении?
Нет. Стандартные компоненты iOS часто поддерживают масштабирование, но разработчик должен правильно выбрать текстовые стили и не перезаписать их фиксированным шрифтом. Кроме того, необходимо проверить компоновку: автоматическое изменение кегля не исправляет жёсткие ограничения, обрезку строк и фиксированную высоту контейнеров.
Можно ли использовать собственный шрифт вместе с Dynamic Type?
Да. Собственный шрифт нужно масштабировать относительно подходящего системного текстового стиля, например body или headline. В UIKit для этого используется UIFontMetrics. После подключения проверьте высоту строк, начертания, кириллицу и поведение текста в крупных категориях доступности.
Нужно ли увеличивать иконки вместе со шрифтом?
Не всегда. Иконка обычно остаётся самостоятельным визуальным элементом, а её размер выбирают по роли и удобству нажатия. При увеличении текста следует проверить расстояние между иконкой и подписью, выравнивание и доступную область действия, но не увеличивать графику автоматически без дизайнерского обоснования.
Как проверить Dynamic Type без ручного просмотра всех экранов?
Автоматизация полезна для проверки доступности ключевых элементов и отсутствия обрезки, но визуальный просмотр всё равно необходим. Снимки экранов в разных категориях помогают сравнить компоновку, а UI-тесты могут искать недоступный текст и проверять наличие элементов управления. Для каждого важного экрана нужен сценарий с длинными строками.
Что делать, если крупный текст ломает таблицу?
Сначала определите, обязательна ли табличная компоновка. Часто её можно заменить вертикальным списком, раскрывающимися строками или отдельным экраном деталей. Если таблица необходима, разрешите переносы, добавьте горизонтальную прокрутку только там, где она понятна пользователю, и не скрывайте важные значения ради сохранения исходной плотности.
Влияет ли Dynamic Type на веб-контент внутри приложения?
Веб-контент и встроенные веб-представления требуют отдельной настройки. Нативные текстовые стили UIKit или SwiftUI не управляют автоматически всей HTML-типографикой внутри страницы. Нужно согласовать масштабирование веб-контента, размеры текста и поведение прокрутки, чтобы пользователь не получил два несвязанных режима изменения шрифта.
Нужно ли учитывать жирный текст отдельно от Dynamic Type?
Да. Крупный размер и жирное начертание по-разному влияют на ширину и высоту строк. Включите системную настройку жирного текста во время проверки, убедитесь, что начертания не исчезают у собственного шрифта, а кнопки и заголовки не начинают обрезаться. Контраст и различимость должны сохраняться во всех поддерживаемых режимах.
Вывод: адаптивная типографика начинается с роли текста
Dynamic Type на iOS — это не отдельная кнопка и не простое увеличение кегля. Надёжный результат получается, когда разработчик использует семантические текстовые стили, масштабирует собственную гарнитуру через системные метрики и заранее проектирует гибкую компоновку. Проверьте экран в крупных категориях, сохраните читаемость и не жертвуйте содержанием ради фиксированного макета.
Если вы создаёте собственную гарнитуру для приложения, начните с тестирования кириллицы, начертаний и читаемости на разных размерах. Создать и подготовить шрифт для интерфейса можно на fontgenerator.ru, а затем подключить его к iOS-проекту с корректным масштабированием под настройки пользователя.