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?
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:
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) } ))
}
}
}