'How could I use a SwiftUI LazyVGrid to create a staggered grid?
Solution 1:[1]
Beau Nouvelle solution is working, however, it's buggy and glitchy at least of me. Instead of using LazyVGrid if we use HStack with alignment: .top It works better.
Here is the view
var body: some View {
HStack(alignment: .top) {
LazyVStack(spacing: 8) {
ForEach(splitArray[0]) {...}
}
LazyVStack(spacing: 8) {
ForEach(splitArray[1]) {...}
}
}
}
Here is the code to split the array
private var splitArray: [[Photo]] {
var result: [[Photo]] = []
var list1: [Photo] = []
var list2: [Photo] = []
photos.forEach { photo in
let index = photos.firstIndex {$0.id == photo.id }
if let index = index {
if index % 2 == 0 {
list1.append(photo)
} else {
list2.append(photo)
}
}
}
result.append(list1)
result.append(list2)
return result
}
I know this is not performance but so far only working solution I found.
Solution 2:[2]
- Split your array into the number of columns you need.
- Inside your LazyVGrid create 2 VStacks.
- Drop a ForEach in both VStacks and use each of your arrays you created earlier to fill them out.
- That’s it
A rough example as follows...
// split array
let splitArrays = ([TileItem], [TileItem])
ScrollView {
LazyVGrid(*setup GridItems here*) {
VStack {
ForEach(splitArrays.0) { tile in
Image(tile.image)
}
}
VStack {
ForEach(splitArrays.0) { tile in
Image(tile.image)
}
}
}
}
It's likely that this isn't very performant, but it should be able to do what you're after.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 |


