Как получить размер представления в SwiftUI
В SwiftUI компоновка представлений зависит от их текущего состояния, которое формируется на основе внутренних свойств, внешних параметров и значений из среды.
Однако в некоторых случаях, особенно при создании сложных пользовательских интерфейсов, родительскому представлению может понадобиться знать размеры своих дочерних элементов.
Давайте разберёмся, как можно получить эту информацию.
📏 Чтение размера представления
В SwiftUI существует инструмент для работы с размерами представлений — GeometryReader.
Этот контейнер заполняет все доступное пространство и предоставляет GeometryProxy, который даёт доступ к параметрам окружающей среды, таким как размер и система координат.
Пример использования:
Однако GeometryReader захватывает всё доступное пространство, а нам зачастую нужно просто узнать размеры конкретного элемента.
Здесь на помощь приходят модификаторы .background() и .overlay(), которые позволяют встроить GeometryReader без изменения размеров основного представления:
Чтобы GeometryReader не мешал макету, можно использовать Color.clear — это создаст невидимый слой:
🔄 Передача данных от ребёнка к родителю
SwiftUI не позволяет напрямую передавать информацию "снизу вверх" по иерархии представлений, но для этого есть механизм PreferenceKey.
Создадим ключ для хранения размера представления:
Затем используем .preference() для передачи данных:
А теперь — способ получения этих данных в родительском представлении:
Любое родительское представление может подписаться на изменения этого ключа через .onPreferenceChange(), получая актуальные размеры.
📌 Улучшение кода с помощью расширения
Такой способ измерения размера элемента полезен настолько часто, что его удобно вынести в расширение:
Теперь использование сводится к одной строке:
🏁 Итоги
Мы разобрали, как в SwiftUI можно передавать информацию о размере представлений с помощью GeometryReader, PreferenceKey и .onPreferenceChange().
Этот метод позволяет динамически адаптировать интерфейс и использовать полученные размеры для построения сложных макетов.
А как вы применяете PreferenceKey в своих проектах? Делитесь идеями и примерами! 🚀
Спасибо за чтение, и до встречи в следующих статьях! 😊