Как использовать GeometryReader в LazyVGrid
Я создаю сетку из карточек, у которых есть изображение вверху и немного текста внизу. Вот быстрый UI-код для компонента:
struct Main: View {
var body: some View {
ScrollView {
LazyVGrid(columns: .init(repeating: .init(.flexible()), count: 2)) {
ForEach(0..<6) { _ in
ZStack {
Rectangle()
.foregroundColor(Color(UIColor.random))
VStack {
Rectangle()
.frame(minHeight: 72)
Text(ipsum)
.fixedSize(horizontal: false, vertical: true)
.padding()
}
}.clipShape(RoundedRectangle(cornerRadius: 10))
}
}.padding()
}.frame(width: 400, height: 600)
}
}
Этот компонент выводит следующий макет:
Это выглядит великолепно, но я хочу добавить считыватель геометрии в компонент Card, чтобы масштабировать вид верхнего изображения в соответствии с шириной окружающего столбца сетки. Насколько мне известно, этот код должен выглядеть следующим образом:
struct Main: View {
var body: some View {
ScrollView {
LazyVGrid(columns: .init(repeating: .init(.flexible()), count: 2)) {
ForEach(0..<6) { _ in
ZStack {
Rectangle()
.foregroundColor(Color(UIColor.random))
VStack {
GeometryReader { geometry in
Rectangle()
.frame(minHeight: 72)
Text(ipsum)
.fixedSize(horizontal: false, vertical: true)
.padding()
}
}
}.clipShape(RoundedRectangle(cornerRadius: 10))
}
}.padding()
}.frame(width: 400, height: 600)
}
}
Проблема в том, что это выглядит следующим образом:
Как видите, я даже не пытаюсь использовать GeometryReader, я просто добавил его. Если я добавлю считыватель геометрии на верхнем уровне, он будет правильно отображать сетку, однако это не очень полезно для меня, потому что я планирую абстрагировать компоненты в другие структуры, соответствующие представлению. Кроме того, GeometryReader кажется полезным с точки зрения контекста, и было бы бессмысленно делать кучу математических расчетов, чтобы сократить значение ширины вдвое, а затем делать свои вычисления оттуда, учитывая, что геометрия будет с верхнего уровня (полная ширина).
Я неправильно использую считыватель геометрии? Насколько я понимаю, его можно использовать в любом месте дерева компонентов, а не только на верхнем уровне.
Спасибо, что заглянули!
1 ответ
У меня была та же проблема, что и у вас, но я решил ее. Вот некоторый ключевой момент.
Если вы установите GeometryReader внутри
По этой причине ваш взгляд выглядит как длинная черная полоса. Вы можете контролировать высоту, установив
Как правило, для реализации этого нам нужно два GeometryReader. Первый может получить размер и выполнить некоторые вычислительные операции, а затем перейти ко второму.
(Поскольку мой исходный код содержит китайский язык, вам может быть трудно его читать, поэтому я могу дать вам только простую структуру.)
GeometryReader { firstGeo in
LazyVGrid(columns: rows) {
ForEach(dataList) { data in
GeometryReader { secondGeo in
// subview
}
.frame(width: widthYouWantSubViewGet)
}
}
}
Я только начал изучать свифт в течение недели. В моем понимании могут быть ошибки. Вы можете помочь исправить это.