LazyVGrid and LazyHGrid, one is a vertical grid layout and the other is a horizontal grid layout. The new layout manager of iOS14, like LazyVGrid and LazyHStack with Lazy
, indicating that Layout managers will only drawing the child elements when need to be displayed.
LazyVGrid
LazyVGrid fills the layout by specifying the number of columns.
01 |
02 |
|
|
The filling order of LazyVGrid is from the top row by row, and when one row is filled, will fill the next row. It’s easy to understand from the alphabetical displayed in the above figure.
The Code of Left Picture
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
var columns: [GridItem] = [
GridItem(.fixed(100)),
GridItem(.fixed(100)),
GridItem(.fixed(100))
]
var body: some View {
// you can use colums array or directory write code in the lines.
// LazyVGrid(columns: columns) {
LazyVGrid(columns: [GridItem(.fixed(100)), GridItem(.fixed(100)), GridItem(.fixed(100))]){
ForEach(0 ..< 30){ index in
RoundedRectangle(cornerRadius: 5)
.foregroundColor(Color(hue: 0.03 * Double(index) , saturation: 1, brightness: 1))
.frame(height: 50)
.overlay(Text("\(String(Unicode.Scalar(65 + index)!))"))
}
}
.padding()
}
|
The Code of Left Picture
1
2
3
4
5
6
7
8
9
10
11
12
13
|
// The row spacing can be adjusted by setting the spacing of LazyVGrid
var body: some View {
LazyVGrid(columns: [GridItem(.fixed(100)), GridItem(.fixed(100)), GridItem(.fixed(100))], spacing: 30){
ForEach(0 ..< 30){ index in
RoundedRectangle(cornerRadius: 5)
.foregroundColor(Color(hue: 0.03 * Double(index) , saturation: 1, brightness: 1))
.frame(height: 50)
.overlay(Text("\(String(Unicode.Scalar(127881 + index)!))"))
}
}
.padding()
}
|
LazyVGrid can make the Header and Footer hover at the top and bottom when scrolling by setting the PinnedViews type. Set the header and footer of Section through Section.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
VStack {
ScrollView {
LazyVGrid(columns: [GridItem(.fixed(100)), GridItem(.fixed(100)), GridItem(.fixed(100))], pinnedViews: [.sectionHeaders, .sectionFooters]){
ForEach(0 ..< 5){ index in
Section(header: Text("Header \(index)")
.bold()
.font(.title)
.frame(maxWidth: .infinity, alignment: .leading)
.background(Color.white),
footer: Text("Footer \(index)")
.bold()
.font(.title)
.frame(maxWidth: .infinity, alignment: .leading)
.background(Color.white)
) {
ForEach(0 ..< 10){ idx in
RoundedRectangle(cornerRadius: 5)
.foregroundColor(Color(hue: 0.03 * Double(index * 10 + idx) , saturation: 1, brightness: 1))
.frame(height: 50)
.overlay(Text("\(index * 10 + idx)"))
}
}
}
}
.padding()
}
}
.clipped()
|
01 |
02 |
|
|
GridItem
GridItem controls the width by the GridSize
Enumeration Cases
GeometryReader is a special View that can get coordinate size information.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
var body: some View {
LazyVGrid(columns: [GridItem(.flexible()), GridItem(.adaptive(minimum: 50), spacing: 0)]){
ForEach(0 ..< 30){ index in
GeometryReader{ proxy in
RoundedRectangle(cornerRadius: 5)
.foregroundColor(Color(hue: 0.1 * Double(index) , saturation: 1, brightness: 1))
.overlay(Text("\(proxy.size.width)"))
}
.frame(height: 50)
}
}
.padding()
}
|
1
2
3
4
5
6
7
8
9
10
|
var body: some View {
LazyVGrid(columns: [GridItem(.flexible(), spacing: 10), GridItem(.flexible(), spacing: 100), GridItem(.flexible(), spacing: 50)]){
ForEach(0 ..< 30){ idx in
RoundedRectangle(cornerRadius: 5)
.foregroundColor(Color(hue: 0.0333 * Double(idx) , saturation: 1, brightness: 1))
.frame(height: 50)
}
}
.padding()
}
|
We can see from the running effect that only the set space will be added to the right side of the grid.
Effect |
|
Alignment
Alignment: use this property to anchor the view’s relative position to the same relative position in the view’s assigned grid space. Similar to the usage of frame's Alignment.
1
2
3
4
5
6
7
8
9
10
|
var body: some View {
LazyVGrid(columns: [GridItem(.flexible(), alignment: .topLeading), GridItem(.flexible(), alignment: .bottomLeading), GridItem(.flexible(), alignment: .trailing)]) {
ForEach(0 ..< 30, id: \.self){ index in
RoundedRectangle(cornerRadius: 5)
.foregroundColor(Color(hue: 0.01 * Double(index * 10), saturation: 1, brightness: 1))
.frame(width: CGFloat((index % 3) + 1) * 20, height: CGFloat((index % 3) + 1) * 20)
}
}
.padding()
}
|
Effect |
|
LazyHGrid
LazyHGrid
and LazyVGrid
are simliar in uasge. LazyHGrid specified the number of rows, fill the specified number of rows from top to bottom, and then fills the second column.
How to achieve an irregular
Effect |
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
var body: some View {
LazyVGrid(columns: [GridItem(.flexible()), GridItem(.flexible()), GridItem(.flexible())]){
ForEach(0 ..< 11){ idx in
GeometryReader { r in
RoundedRectangle(cornerRadius: 5)
.foregroundColor(Color(hue: 0.1 * Double(idx) , saturation: 1, brightness: 1))
.frame(width: idx == 6 ? 2 * r.size.width + 10 : r.size.width )
}
.frame(height: 100)
if idx == 6 {
Color.clear
}
}
}
.padding()
}
|