Why is LazyHGrid not as high as its items?

401 Views Asked by At

I've got a LazyHGrid that shows multiple Text views in one row. That LazyHGrid is inside a VStack. However, the LazyHGrid is higher than it needs to be. What causes the extra space?

struct ContentView: View {

    let rows = [GridItem()]

    var body: some View {
        VStack {
        
            ScrollView(.horizontal) {
                LazyHGrid(rows: rows) {
                    ForEach(0..<10) { index in
                        Text("Test \(index)")
                            .padding()
                            .foregroundColor(Color.white)
                            .background(Color.black)
                    }
                }
            }
            .background(Color.green)
        
            ScrollView(.vertical) {
                VStack {
                    ForEach(0..<100) { index in
                        Text(String(index))
                            .frame(maxWidth: .infinity)
                    }
                }
            }
            .background(Color.blue)
        }
    }
}

enter image description here

2

There are 2 best solutions below

4
On BEST ANSWER

You just have to add .fixedSize() modifier to your grid, and it works...

                LazyHGrid(rows: rows) {
                    ForEach(0..<10) { index in
                        Text("Test \(index)")
                            .padding()
                            .foregroundColor(Color.white)
                            .background(Color.black)
                    }
                }
                .fixedSize()

With fixedSize()

0
On

This works: Reading the height of the cells with an overlay with GeometryReader

struct ContentView: View {
    
    let rows = [ GridItem() ]
    @State private var contentSize = CGFloat.zero
    
    var body: some View {
        VStack {
            
            ScrollView(.horizontal) {
                LazyHGrid(rows: rows) {
                    ForEach(0..<10) { index in
                            Text("Test \(index)")
                                .padding()
                                .foregroundColor(.white)
                                .background(.black)
                            
                                .overlay(
                                    GeometryReader { geo in
                                        Color.clear.onAppear {
                                            contentSize = geo.size.height
                                        }
                                    }
                                )

                    }
                }
            }
            .frame(height: contentSize + 20)
            .background(Color.green)
            
            ScrollView(.vertical) {
                VStack {
                    ForEach(0..<100) { index in
                        Text(String(index))
                            .frame(maxWidth: .infinity)
                    }
                }
            }
            .background(Color.blue)
        }
    }
}