How to make a lazyvgrid/ lazyhgrid scroll horizontally maintaining its appearance?

3.1k Views Asked by At

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.

What i want to achieve:
enter image description here

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:
enter image description here

  • 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 enter image description here 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:
enter image description here

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…

1

There are 1 best solutions below

0
On BEST ANSWER

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