在SwiftUI
中,我们可以使用LazyVGrid
或LazyHGrid
视图创建一个二维响应列表。如果我们想要一个垂直网格,我们可以使用LazyVGrid
视图,如果我们想要一个水平网格,可以使用LazyHGrid
视图。这些视图允许我们创建一个网格的项目,以适应不同的方向和屏幕大小。
LazyVGrid和LazyHGrid
struct GridDemo: View {
private var data = Array(1...50)
private var columns: [GridItem] = [
GridItem(.fixed(50)),
GridItem(.fixed(50)),
GridItem(.fixed(50))
]
var body: some View {
ScrollView{
LazyVGrid(columns: columns, spacing: 20) {
ForEach(data, id: \.self) { item in
Text(String(item))
.frame(width: 50, height: 50, alignment: .center)
.background(.blue)
.cornerRadius(10)
.foregroundColor(.white)
.font(.title)
}
}
}
.padding()
}
}
在上面的例子中,我们使用LazyVGrid
创建了一个显示50个Text
的网格。首先,用GridItem
定义了一些列。在这里,我们通过设置.fixed(50)
定义了三个固定宽度为50的列。
然后,我们将网格视图放入滚动视图中,使其可滚动。最后,指定列作为LazyVGrid
的参数。这就是我们在SwiftUI
中创建网格布局所需要做的一切。
LazyVGrid
:竖向滚动,按行从左向右加载每一项,从上往下加载每一行。每行的第一个项组成一列,依次向右为第二列,第三列等。
LazyHGrid
:横向滚动,按列从上到下加载每一项,从左向右加载每一列。每列的第一个项组成一行,从上向下依次为第一行,第二行等。
GridItem
GridItem
主要是对这种二维的网格布局的行或者列的一种描述。要想配置二维网格布局,我们需要创建一个包含GridItem
实例的一个数组。每一个GridItem
实例都描述了LazyVGrid
中的一列或者LazyHGrid
中的一行的size
,spacing
和alignment
信息。
初始化GridItem
的方法如下:
init(
_ size: GridItem.Size = .flexible(),
spacing: CGFloat? = nil,
alignment: Alignment? = nil
)
GridItem Size
其中GridItem.Size
是一个枚举,有三种类型:
/// 这种类型将一个或多个项目放入到单个灵活的空间中,使用提供的边界和间距来
/// 确定适合多少项。这种方法倾向于尽可能多地插入最小大小的项,但让它们增加到最大大小。
case adaptive(minimum: CGFloat, maximum: CGFloat)
/// 这种类型指定了固定的值用于列的宽度或者行的高度。
case fixed(CGFloat)
/// 这种类型的大小是删除间隔和非灵活项后的网格大小,除以固定在提供边界内的灵活项的数量。
case flexible(minimum: CGFloat, maximum: CGFloat)
说起来还是不太好理解。
比如说我们想在LazyVGrid
的一行或者LazyHGrid
的一列显示尽可能多的item,我们可以用adaptive()
,比如设置GridItem(.adaptive(minimum: 50))
,那么就会以最小50的距离尽可能的排列更多的item。
LazyVGrid
LazyHGrid
如果要控制每列或行中的数量,可以使用flexible()
。但是,如果没有足够的空间容纳视图的最小尺寸,则每项之间可能会重叠。
LazyVGrid
LazyHGrid
如果就像给列或者行设置一个固定的尺寸,可以使用fixed()
。
LazyVGrid
LazyHGrid
GridItem Spacing
Spacing
定义了当前项与下一项的间距。如果此值为nil
,则该项使用当前平台的合理默认值。
下面是一个五列网格的示例,其中列中每个项目之间的间距分别为0、10、20、30、40。
struct GridDemo: View {
private var data = Array(1...50)
private var columns: [GridItem] = [
GridItem(.fixed(50), spacing: 0),
GridItem(.fixed(50), spacing: 10),
GridItem(.fixed(50), spacing: 20),
GridItem(.fixed(50), spacing: 30),
GridItem(.fixed(50), spacing: 40)
]
var body: some View {
ScrollView() {
LazyVGrid(columns: columns) {
ForEach(data, id: \.self) { item in
Text(String(item))
.frame(width: 50, height: 50, alignment: .center)
.background(.blue)
.cornerRadius(10)
.foregroundColor(.white)
.font(.title)
}
}
}
.padding()
}
}
这里需要注意的是最后一列定义的spacing是40,但是因为这个是最后一列,所以这个40就被忽略了。
在看一下采用LazyHGrid
的效果:
struct GridDemo: View {
private var data = Array(1...50)
private var columns: [GridItem] = [
GridItem(.fixed(50), spacing: 0),
GridItem(.fixed(50), spacing: 10),
GridItem(.fixed(50), spacing: 20),
GridItem(.fixed(50), spacing: 30),
GridItem(.fixed(50), spacing: 40)
]
var body: some View {
ScrollView(.horizontal) {
LazyHGrid(rows: columns) {
ForEach(data, id: \.self) { item in
Text(String(item))
.frame(width: 50, height: 50, alignment: .center)
.background(.blue)
.cornerRadius(10)
.foregroundColor(.white)
.font(.title)
}
}
}
.padding()
}
}
GridItem Alignment
放置每个视图时使用的对齐方式。使用此属性将视图的相对位置锚定到视图分配的网格空间中的相对位置。
默认情况下,每个项目将在行/列内居中对齐。我们可以通过alignment
属性来改变这个。
写在最后
文章中主要介绍了LazyVGrid
和LazyHGrid
的主要用法,包括布局类型,间距和对齐等属性的设置,希望能够让大家更直观的了解LazyVGrid
和LazyHGrid
的使用,下一篇文章我们一起看一下iOS 16
新推出的Grid
和GridRow
的用法。
最后,希望能够帮助到有需要的朋友,如果您觉得有帮助,还望点个赞,添加个关注,笔者也会不断地努力,写出更多更好用的文章。