January 13, 2024
49. Получаем размер вьюшки в SwiftUI
Иногда бывает нужно получить размер вьюшки, чтобы сверстать что-то особым образом. Например, нужно расположить один UI-элемент на определенном расстоянии от другого, но они оба находятся в разных контейнерах, т.е. обычным VStack/HStack и спейсингом не обойтись.
Есть достаточно простое решение для такой ситуации: GeometryReader + PreferenceKey, и в этой статье покажу как с этим работать.
Будем использовать PreferenceKey, как это часто бывает, для передачи информации о вьюхе наверх по иерархии вьюшек:
struct SizePreferenceKey: PreferenceKey {
static var defaultValue: CGSize = .zero
static func reduce(value: inout CGSize, nextValue: () -> CGSize) {}
}
Делаем модификатор для получения размера:
extension View {
/// Возвращает размер вьюхи в замыкании
func readSize(onChange: @escaping (CGSize) -> Void) -> some View {
background(
GeometryReader { geometry in // <- незаменимый и неповторимый
Color.clear
.preference(key: SizePreferenceKey.self, value: geometry.size)
}
)
.onPreferenceChange(SizePreferenceKey.self, perform: onChange)
}
}
Код для этой статьи можно посмотреть тут, а другие статьи - тут.