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

Комментарии (0)