4

So I am trying to get a custom grid with cells of different size. I have kinda gotten stuck here. So I have one particular cell with the height and size double that of all the others. But the left side of the cell requires two rows instead of one. How can I force to add two more boxes below H3 or to left of H4 box in the picture below.

Here is my code:

struct CustomGridView: View {
var body: some View {
    let gridItems = [GridItem(.fixed(150), spacing: 10, alignment: .leading),
                     GridItem(.fixed(150), spacing: 10, alignment: .leading),
                     GridItem(.fixed(150), spacing: 10, alignment: .leading)]

    LazyVGrid(columns: gridItems, spacing: 10) {
        ForEach(0..<9) { g in
            
            Text("H:\(g)")
                .frame(width: g == 4 ? 310 : 150, height: g == 4 ? 310 : 150)
                .background(Color.red)
            
            if g == 4 { Color.clear }
            
        }
    }
    .frame(width: 470)
}
}

Here is the screen shot of the grid situation so far:

enter image description here

Any help with this will be appreciated.

Osama Naeem
  • 1,830
  • 5
  • 16
  • 34

2 Answers2

0
struct ContentView: View {
var body: some View {
    let gridItems = [GridItem(.fixed(150), spacing: 10, alignment: .leading),
                     GridItem(.fixed(150), spacing: 10, alignment: .leading),
                     GridItem(.fixed(150), spacing: 10, alignment: .leading)]

    LazyVGrid(columns: gridItems, spacing: 10) {
        ForEach(0..<9) { g in
            
            Text("H:\(g)")
                .frame(width: g == 4 ? 310 : 150, height: g == 4 ? 310 : 150)
                .background(Color.red)
                .frame(height: 150, alignment: .top)
            
            if g == 4 {
                Color.clear
            }
            if g == 5 {
                Group {
                    Color.clear
                    Color.clear
                }
            }
        }
    }
    .frame(width: 470)
}

enter image description here

Your approach was close enough, but needed 2 fixes:

  1. The H:4 cell is double the size and double the width, so it is 4x bigger, and needs 3 extra "clear" bogus-cells. I've added one on the same row, and 2 on the next row to achieve the desired layout
  2. The height of H:4 was 310, which is used by the LazyVGrid to determine the height of the entire row as 310. I fixed that with .frame(height: 150, alignment: .top), causing the grid to think that H:4 cell actually has height 150, and letting the content to "leak out" of the cell. Top alignment is needed to make sure the content leaks out down, not in all directions at once
Maksim Gayduk
  • 1,051
  • 6
  • 13
-1

I don't think you can do that when just using lazy vgrid ForEach... Perhaps you can do something like that if you check for highest cell height in a row and then somehow fill it with two more boxes. You'd need to write a custom function for that. Also which block will go into the blank space above/below H:3? You'd need to write some custom logic for that.