swiftswiftuigeometryreaderlazyvgrid

How to use GeometryReader within LazyVGrid to correctly define size of the View within ForEach?


Quick test case. Layout is broken if GeometryReader is applied.

struct TestGridView: View {
    var body: some View {
        ScrollView {
            LazyVGrid(columns: [GridItem(.adaptive(minimum: 140))], spacing: 10) {
                ForEach(0 ..< 100) { index in
                    GeometryReader { geo in
                        Text("Cell \(index)")
                            .frame(width: geo.size.width, height: geo.size.width)
                            .background(in: RoundedRectangle(cornerRadius: 10))
                            .backgroundStyle(.red)
                    }
                }
            }
        }
    }
}


#Preview {
    TestGridView()
}

Here is an example without GeometryReader for .frame(width: 100, height: 100). This is not what i want.

enter image description here

Here is how it looks with the issue because of GeometryReader.

enter image description here

What do I need? I need squares there with the same height as its width. Within that squares there is Image loaded from an url. But here it is not important.

Here is suggested solution how to get frame from within background view to use it later for something... but it is not useful for my case. Because I would need it to use it on the View where frame was computed from (in background()).


Solution

  • I need squares there with the same height as its width

    Try using .aspectRatio instead:

    ForEach(0 ..< 100) { index in
        Text("Cell \(index)")
            .frame(maxWidth: .infinity, maxHeight: .infinity)
            .aspectRatio(1, contentMode: .fit)
            .background(.red, in: .rect(cornerRadius: 10))
    }
    

    Screenshot