
Если вы решили посвятить свой нелегкий путь разработчика React Native, то почти наверняка уже столкнулись с проблемой автоматического растягивания текста. Или (спойлер) столкнетесь с ней в ближайшем будущем. Немало часов я провел на форумах для поиска универсального решения. Меж тем, вводных для авторесайза текст-компонента в мобильных приложениях может быть великое множество - используемая платформа, утвержденный дизайн, который должен быть одинаковым на всех девайсах, анимации, размер девайса, объем текста, размер шрифта и т.д. Готовое универсальное решение нам не удалось обнаружить даже на любимом https://stackoverflow.com/. Поэтому каждый программист справляется с проблемой автоматического ресайза текста по-своему.
Сегодня, опираясь на опыт разработки мобильных приложений в SDVentures, я смог выделить три оптимальных решения в зависимости от задачи, которыми и поделюсь с вами.
Итак в материале ниже расскажу о задачах, которые решает тот или иной вид авторесайза, их плюсы и минусы, опишу готовые библиотеки для каждого решения. Поехали!
Автоматический ресайз с «коробки» React Native
С версий 0.6х React Native сильно продвинулся в плане создания готового решения для авторесайза текста на обе платформы. Поэтому логично будет начать с него.
Само решение — это параметр для текста adjustsFontSizeToFit. При восстановлении в тексте style с параметром fontSize (который для данного решения будет максимальным) и другими параметрами, которые завязаны на размерах текстового компонента, вы получите сразу автоматический ресайз для нужного компонента.
Казалось бы — идеальный вариант найден! Но не тут то было, у решения есть важный минус: для платформы android невозможно выставить нижнюю границу уменьшения текста. Используя adjustsFontSizeToFit вы не сможете узнать через события, какой же получился итоговый fontSize для вашего <Text/>.
У iOS платформы в решении есть ограничитель minimumFontScale. Но прежде чем говорить об этом подробнее давайте присмотримся к тому, насколько он может быть полезен в гипотетическом кейсе.
Нам нужна строчка с автоматическим ресайзом текста без ellipsizeMode эффекта. Однако в технической задаче указано, что текст может быть любым по количеству символов.
Получается, что даже на iOS платформе при выставлении параметра minimumFontScale можно получить об��езанный текст, если сам текст будет длинным относительно строки. Поэтому важно заранее просчитывать и учитывать самые "критические" кейсы.
Задачи, где можно использовать решение:
Строгий статический или небольшой текст, который точно поместится на устройстве любого размера.
Плюсы:
простота использования;
все расчёты размеров происходят на нативной стороне, поэтому не страдает производительность.
Минусы:
невозможность выставления нижних границ размера шрифта;
гипотетическая возможность обрезаемости динамического текста.
Библиотеки:
https://reactnative.dev/docs/text
Автоматический ресайз от размера устройства
Название этого решения хорошо описывает задачу, которая стоит перед разработчиком. Предположим, что в дизайне продукта присутствует текстовый заголовок. Желательно, чтобы он отображался примерно одинаково на всех устройствах.
Какие данные мы имеем: размер девайса, максимальный и гипотетически минимальный размер текста.
Оптимальное решение: создать утилиту для расчета размера в стилях текста. При помощи математики необходимо процентно рассчитывать от 0 до 1 разницу между минимальным и максимальным значениями, приплюсовать рассчитанную разницу к минимальному значению.
Подобное решение можно и адаптировать. Допустим, мы замиксуем в него количество символов текста, процентное соотношение высоты и ширины девайса, прочие данные. Одно остается неизменным — грамотные математические расчёты, которые вычитаются при первой отрисовке компонента при помощи вашей утилиты в стилях.
Задачи, в которых можно использовать решение:
Статические тексты под размер девайса, например, текст на кнопке внизу страницы, ярко выраженный тайтл для страницы.
Плюсы:
ручная настройка размеров по нужным параметрам (даже минимальный размер текста);
отсутствие лишних перерисовываний страницы;
прописывание математической логики.
Минусы:
существует в основном для тривиальных решений;
не самое идеальное решение, которое подходит только под конкретные задачи и условия.
Библиотека:
https://www.npmjs.com/package/react-native-responsive-fontsize
Автоматический ресайз при помощи ручной настройки
Иногда разработчикам попадаются многострочные бизнес-задачи, которые могут ограничивать на конкретное количество строк при конкретных значениях размера текста.
Оптимальное решение в такой ситуации: обвязать <Text/> с помощью onTextLayout или onLayout. Единственный минус такого решения заключается в том, что если первое условие после любого слушателя оказывается невалидным, то нужно будет перерисовывать компонент после новой попытки n-количество раз. Но даже этой неприятной ситуации можно избежать, если попросить ограничить количество таких кейсов у заказчика. Например, можно выбрать 3 или 4 возможных варианта размера текстового компонента.
Задачи, в которых можно использовать решение:
Многострочные тексты с продвинутой бизнес-логикой задач.
Плюсы:
При помощи слушателей можно рассчитать почти всё что угодно.
Минусы:
Лишние перерисовывания.
Вместо вывода
Для React Native пока не существует единого решения, которое бы идеально вписалось именно в вашу задачу. Приведенные туториалы могут помочь в большинстве сценариев, но всегда есть место исключениям. И будем надеяться, что в ближайшем будущем мы исключим все “но” из этих решений. Главный совет, который я могу дать (после всех набитых шишек) — внимательно читайте документацию. Вам, как программисту, важно понимать, какие вводные данные у вас е��ть, и заранее переспросить у менеджера про возможные риски и масштабирование задачи. Хотелось бы верить, что Гугл действительно знает все, но мы с вами понимаем, что это далеко не так.
