在本章中,你将学会使用LazyVGrid
垂直网格和LazyHGrid
水平网格建立网格布局。
在前面的章节中,我们学习了VStack
垂直排布、HStack
水平排布、ZStack
层叠排布,它们可以将多个元素按照不同的排布方式展示在页面上。
但在有些场景下,由于设备屏幕大小限制、设配平台的不同,不能采用单纯的排布方式,示例:一款App
同时兼容iPhone
和iPad
时,在iPhone
的布局和iPad
上的布局会存在很大的差异,但这不代表这我们需要开发两套代码单独维护。
在本章中,我们将使用LazyVGrid
垂直网格和LazyHGrid
水平网格进行页面布局。
首先,创建一个新项目,命名为SwiftUILazyGrid
。
数据准备
为了更好地理解网格布局,我们先准备一些Apple
的系统图标作为示例。
private var appleSymbols = ["house.circle", "person.circle", "bag.circle", "location.circle", "bookmark.circle", "gift.circle", "globe.asia.australia.fill", "lock.circle", "pencil.circle", "link.circle"]
在我们使用网格布局时,我们要定义的网格是多少列,然后再按照实际的数量,系统可以自动排布多少行。
这里,我们先定义3
列。
private var gridItemLayout = [GridItem(.flexible()), GridItem(.flexible()), GridItem(.flexible())]
LazyVGrid垂直网格
数据准备好后,我们尝试使用LazyVGrid
垂直网格和ScrollView
滚动视图来实现网格布局。
ScrollView { LazyVGrid(columns: gridItemLayout, spacing: 20) { ForEach(0 ... 99, id: \.self) { Image(systemName: appleSymbols[$0 % appleSymbols.count]) .font(.system(size: 30)) .frame(width: 80, height: 80) .background(Color(.systemGray6)) .cornerRadius(10) } } }
我们使用了LazyVGrid
垂直网格,布局列数为gridItemLayout
内的3
列,间距为20
,使用ForEach
循环遍历100
条图片数据。
不错的样子。
如果需要在不同屏幕上展示的Image
图片背景不同,我们可以调整下.frame
尺寸修饰符。
.frame(minWidth: 0, maxWidth: .infinity, minHeight: 80)
这样,图片视图之间就均匀分布啦。
spacing网格间距
如果我们调整网格间距,可以直接将LazyVGrid
垂直网格的Spacing
去掉。
但这不能完全去掉图片视图之间的间距,这是因为LazyVGrid
垂直网格中的视图之间默认存在一个间距。
要完全去掉间距,我们只能在从gridItemLayout
网格布局调整。
private var gridItemLayout = [GridItem(.flexible(), spacing: 0), GridItem(.flexible(), spacing: 0), GridItem(.flexible(), spacing: 0)]
代码太长了,我们发现每一个GridItem
网格列都要有个spacing
,这里我们可以用数据的方式抽离出来。
private var gridItemLayout = Array(repeating: GridItem(.flexible(), spacing: 0), count: 3)
这样,网格之间的横向遍历的间距已经去掉了。
再调整下LazyVGrid
垂直网格的视图间的间距,这样我们就可以去掉LazyVGrid
垂直网格里的所有视图间距。
flexible灵活适应修饰符
在我们创建LazyVGrid
垂直网格时,我们使用到了.flexible
灵活适应修饰符,这里我们的gridItemLayout
网格为3
列,我们改成4
列看看。
我们创建一个GridItem
数组,它的主体用.flexible
灵活适应修饰符修饰,数量为4
。
private var columnGrid: [GridItem] = Array(repeating: .init(.flexible()), count : 4)
adaptive自适应修饰符
除了flexible
灵活适应修饰符外,我们也可以使用.adaptive
自适应修饰符来自适应调整LazyVGrid
垂直网格内的排布。
private var gridItemLayout = [GridItem(.adaptive(minimum: 80))]
我们设置了GridItem
列项最小的大小的80
,然后使用adaptive
自适应修饰符修饰。
调整后,LazyVGrid
垂直网格会在每个GridItem
列项大小为80
的基础上,在一行中会填充尽可能多的图像。
fixed适应修饰符
如果我们希望修改单个GridItem
列项的宽度,我们可以使用.fixed
适应修饰符。
private var gridItemLayout = [GridItem(.fixed(100)), GridItem(.fixed(150)),GridItem(.
以上三种修饰符,我们还可以根据业务的不同混合使用
。
private var gridItemLayout = [GridItem(.flexible()), GridItem(.fixed(150)),GridItem(
LazyHGrid水平网格
上面我们创建了一个LazyVGrid
垂直网格,LazyHGrid
水平网格的用法与其类似,只需要更改网格类型就行了。
有2点不同的是:
ScrollView滚动视图是默认垂直滚动的,如果我们需要使用LazyHGrid水平网格,那么需要同时设置ScrollView滚动视图滚动方向为水平。
LazyVGrid垂直网格是使用columns列读取数据,而LazyHGrid水平网格是使用rows行读取数据。
ScrollView (.horizontal) { LazyHGrid(rows: gridItemLayout,spacing: 10) { ForEach(0 ... 99, id: \.self) { Image(systemName: appleSymbols[$0 % appleSymbols.count]) .font(.system(size: 30)) .frame(minWidth: 80,minHeight: 80,maxHeight: .infinity) .background(Color(.systemGray6)) .cornerRadius(10) } } }
恭喜你,学会了LazyVGrid
垂直网格和LazyHGrid
水平网格的基础使用!
快来动手试试吧!