如何使 lazyvgrid/lazyhgrid 水平滚动保持其外观?

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

我正在尝试创建一个具有 1 行并水平滚动的 lazyvgrid,但我一定是遗漏了一些东西,因为我尝试的一切都弄乱了我的布局。

我想达到的目标:

像这样的网格(只有 1 行)可以水平滚动

我在做什么:

现在我有两个不满意的方案:

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

结果如下:


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

看起来像这样  现在在这里,如果我们将最小尺寸更改为 200 或另一个大数字,我得到 1 行,但集合视图仍然非常高,相反我只希望它与其中的项目一样高。

作为参考,它看起来像这样:

你能解释一下如何成功实现我所需要的以及为什么会这样吗?我真的很想了解更多关于 swiftui 中的网格的知识,我非常擅长 UIKit 中的集合视图,但在网格中没有相同的视图令人沮丧……

当您设置定义的 .frame(width: 50, height: 50, alignment: .center) 时,您将不需要 GeometryReader

您可以这样做:

        ScrollView(.horizontal){
            LazyHGrid(rows: [ GridItem(.flexible()) ]) {
                ForEach(days, id: \.self) {focus in
                    Circle()
                        .foregroundColor(.yellow)
                        .frame(width: 50, height: 50, alignment: .center)
                }
            }
        }

或完全跳过网格并使用 LazyHStack,如果您只有一行,这将是更自然的选择。:

        ScrollView(.horizontal){
            LazyHStack {
                ForEach(days, id: \.self) {focus in
                    Circle()
                        .foregroundColor(.yellow)
                        .frame(width: 50, height: 50, alignment: .center)
                }
            }
        }