Home > Blockchain >  Break a LazyVGrid into pieces
Break a LazyVGrid into pieces

Time:02-26

I have the following grid made in SwiftUI with this code:

let columnGrid = [GridItem(.fixed(boxWidth), spacing: 0),
                                  GridItem(.fixed(boxWidth), spacing: 0),
                                  GridItem(.fixed(boxWidth), spacing: 0),
                                  GridItem(.fixed(boxWidth), spacing: 0),
                                  GridItem(.fixed(boxWidth), spacing: 0),
                                  GridItem(.fixed(boxWidth), spacing: 0),
                                  GridItem(.fixed(boxWidth), spacing: 0),
                                  GridItem(.fixed(boxWidth), spacing: 0),
                                  GridItem(.fixed(boxWidth), spacing: 0)]

LazyVGrid(columns: columnGrid, spacing: 0) {
                        ForEach((0...80), id: \.self) {
                            Text("\(positions[$0])")
                                .font(.system(size: 27))
                                .frame(width: boxWidth, height: boxWidth)
                                .background(Rectangle().stroke(lineWidth: 0.5))
                        }
                    }

How can I break the grid into pieces? For example, break the grid into groups of 4 blocks.

a b     e g     i j
c d     f h     k l

m n     q r
o p     s t

etc.

Every time I try a combination of LazyVGrid or a massive amount of HStacks and VStacks, it seems super bloated.

I also tried pinned headers with sections but it could only break things up into rows. I want it to break into rows and columns.

Is there a simple way to do this in SwiftUI?

A grid made with LazyVStack

CodePudding user response:

What you are really attempting to do is put a Grid inside of a Grid. With the output you have demonstrated, you want a LazyVGrid inside of a LazyHGrid. The most difficult part will be chunking your data, not the view itself. That can be achieved like this as an example:

enter image description here

struct LazyVGridInLazyHGridView: View {
    
    @StateObject var vm = LazyVGridInLazyVGridViewModel()
    
    let gridsColumn = [GridItem(.flexible(), spacing: 0), GridItem(.flexible(), spacing: 0)]
    let boxColumn = [GridItem(.fixed(30), spacing: 0), GridItem(.fixed(30), spacing: 0)]
    
    var body: some View {
        LazyHGrid(rows: gridsColumn, spacing: 15) {
            ForEach(vm.data, id: \.self) { box in
                LazyVGrid(columns: boxColumn, spacing: 15) {
                    ForEach(box) { item in
                        Text(item.name)
                    }
                }
                .background(Color.gray.opacity(0.15))
            }
        }
        .frame(height: 150)
    }
}

struct VGridDataModel: Identifiable, Hashable {
    let id = UUID()
    var name: String
}

class LazyVGridInLazyVGridViewModel: ObservableObject {
    @Published var data: [[VGridDataModel]] = []
    
    init() {
        for strideIndex in stride(from: 1, to: 20, by: 4) {
            data.append(Array(strideIndex..<(strideIndex   4)).map({ VGridDataModel(name: $0.description) } ))
        }
    }
}
  • Related