In my model, I create an array of objects:
let myObjects = [ theObject(name: "first", ...),
theObject(name: "second", ...), etc.
I want to use the SwiftUI Grid
container view to display the objects' contents in a 2-column layout. But the GridRow
structure is accessing the array more than once per pass, making a ForEach
tricky:
GridRow {
Text(myObjects[i].name)
Text(myObjects[i+1].name)
}
GridRow {
... etc
I'm not sure of the best way to iterate through these objects. Here are three ideas:
1. Don't use Grid
I could use a lazy method (like LazyVGrid), which would lay the objects out as they are enumerated one-by-one. But I like the control and finesse of using this new (iOS 16) Grid container.
2. Change the Model
The model could carry both information in each object:
let myObjects = [ theObject(firstName: "first", secondName: "second", ...),
theObject(firstName: "third", secondName: "fourth", ...), etc.
But yuck, that just smells. And what if I decide to have three columns?
3. Carry a pointer
Use an integer to point to the elements in the array:
ForEach(0...((myObjects.count - 1) / 2), id: \.self) { i in
GridRow {
Text(myObjects[i*2].name)
if (i*2) < myObjects.count - 1 { // to guard against an odd number of elements
Text(myObjects[(i*2) + 1].name)
}
}
}
This also feels painful, and not adaptive if I change the number of columns.
What technique am I not thinking of? Would you consider any of these acceptable?
I ended up using a LazyVGrid
for this.