Как использовать 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 внутри а также , согласно правилу компоновки SwiftUI, GeometryReader получит предложенный размер (может быть всего 10 пунктов). Что еще более важно, независимо от того, какое подпредставление внутри GeometryReader, это не повлияет на размер GeometryReader и родительского представления GeometryReader.

По этой причине ваш взгляд выглядит как длинная черная полоса. Вы можете контролировать высоту, установив ,

Как правило, для реализации этого нам нужно два GeometryReader. Первый может получить размер и выполнить некоторые вычислительные операции, а затем перейти ко второму.

(Поскольку мой исходный код содержит китайский язык, вам может быть трудно его читать, поэтому я могу дать вам только простую структуру.)

      GeometryReader { firstGeo in
    LazyVGrid(columns: rows) {
        ForEach(dataList) { data in
            GeometryReader { secondGeo in
              // subview
            }
            .frame(width: widthYouWantSubViewGet)
        }
    }
}

Я только начал изучать свифт в течение недели. В моем понимании могут быть ошибки. Вы можете помочь исправить это.

Другие вопросы по тегам