I’m trying to create a lazyvgrid which has 1 row and scrolls horizontally but i must be missing something since everything I try messes up my layout.
A grid like this (with just 1 row) that is able to scroll horizontally.
What I am doing:
- I choose a LazyvGrid because of the way the elements are placed in it .
- I tried with a LazyHGrid as well because since I only need a row it’s not that important how the items are placed in the grid. Anyway the layout looked weird (I had multiple rows that i couldn’t remove).
- Consider that despite my array is static, in real life it will be dynamic
Now I have two solutions which I am not satisfied with:
- The one with the lazyvgrid:
var days: [Int] = [1,2,3,4,5,6,7]
[…]
GeometryReader{ geometry in
ScrollView(.horizontal){
LazyVGrid(columns: [GridItem(.adaptive(minimum: geometry.size.width * 0.12))]) {
ForEach(days[0..<days.count], id: \.self) {focus in
Circle()
.foregroundColor(.yellow)
.frame(width: 50, height: 50, alignment: .center)
}
}
}
}
Which results in the following:

- The lazyHgrid solution:
GeometryReader{ geometry in
ScrollView(.horizontal){
LazyHGrid(rows: [GridItem(.adaptive(minimum: geometry.size.width * 0.12))]) {
ForEach(days[0..<days.count], id: \.self) {focus in
Circle()
.foregroundColor(.yellow)
.frame(width: 50, height: 50, alignment: .center)
}
}
}
}
And it looks like this  Now here if we change the minimum size to 200 or another big number, i Get 1 row but the collection view remains very tall, instead i only want it to be as tall as the items inside of it are.
for reference, it looks like this:

Can you explain me how to successfully achieve what i need and why this is happening? I really would like to learn more about grids in swiftui, i was very good with collection views in UIKit and it’s frustrating not having the same with grids…
CodePudding user response:
As you set a defined .frame(width: 50, height: 50, alignment: .center)
you won't need GeometryReader
.
You can do either this:
ScrollView(.horizontal){
LazyHGrid(rows: [ GridItem(.flexible()) ]) {
ForEach(days, id: \.self) {focus in
Circle()
.foregroundColor(.yellow)
.frame(width: 50, height: 50, alignment: .center)
}
}
}
or skip Grid entirely and use LazyHStack
, which would be the more natural pick if you only have one row.:
ScrollView(.horizontal){
LazyHStack {
ForEach(days, id: \.self) {focus in
Circle()
.foregroundColor(.yellow)
.frame(width: 50, height: 50, alignment: .center)
}
}
}