Если вы решили посвятить свой нелегкий путь разработчика 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 пока не существует единого решения, которое бы идеально вписалось именно в вашу задачу. Приведенные туториалы могут помочь в большинстве сценариев, но всегда есть место исключениям. И будем надеяться, что в ближайшем будущем мы исключим все “но” из этих решений. Главный совет, который я могу дать (после всех набитых шишек) — внимательно читайте документацию. Вам, как программисту, важно понимать, какие вводные данные у вас е��ть, и заранее переспросить у менеджера про возможные риски и масштабирование задачи. Хотелось бы верить, что Гугл действительно знает все, но мы с вами понимаем, что это далеко не так.