SwiftUI如何实现包含不同尺寸单元格的自定义网格布局
解决方案
方法1:基于现有LazyVGrid手动补占位
LazyVGrid采用行优先的流式填充逻辑,2x2尺寸的特殊单元格会占用2个列位+2个行位,你只需要补全3个透明占位即可实现你要的布局,修改后代码如下:
struct CustomGridView: View { var body: some View { let gridItems = [GridItem(.fixed(150), spacing: 10, alignment: .leading), GridItem(.fixed(150), spacing: 10, alignment: .leading), GridItem(.fixed(150), spacing: 10, alignment: .leading)] LazyVGrid(columns: gridItems, spacing: 10) { ForEach(0..<12) { g in if g == 4 { // 特殊2x2单元格 Text("H:\(g)") .frame(width: 310, height: 310) .background(Color.red) } else if [5,7,8].contains(g) { // 补3个透明占位:同行列尾1个、下一行前2个 Color.clear .frame(width: 150, height: 150) } else { // 普通单元格,调整序号保证连续 let displayIndex = g < 5 ? g : (g < 7 ? g-1 : g-4) Text("H:\(displayIndex)") .frame(width: 150, height: 150) .background(Color.red) } } } .frame(width: 470) } }
方法2:使用SwiftUI原生Grid组件(推荐,适配iOS 16+/macOS 13+)
SwiftUI 3.0新增的Grid组件原生支持单元格跨行列,不需要手动处理占位,逻辑更清晰:
struct CustomGridView: View { var body: some View { Grid(horizontalSpacing: 10, verticalSpacing: 10) { GridRow { ForEach(0..<3) { idx in Text("H:\(idx)") .frame(width: 150, height: 150) .background(Color.red) } } GridRow { Text("H:3") .frame(width: 150, height: 150) .background(Color.red) Text("H:4") .frame(width: 310, height: 310) .background(Color.red) .gridCellColumns(2) } GridRow { Text("H:5") .frame(width: 150, height: 150) .background(Color.red) ForEach(6..<8) { idx in Text("H:\(idx)") .frame(width: 150, height: 150) .background(Color.red) } } GridRow { ForEach(8..<11) { idx in Text("H:\(idx)") .frame(width: 150, height: 150) .background(Color.red) } } } .frame(width: 470) } }
内容的提问来源于stack exchange,提问作者Osama Naeem
相关产品推荐
相关产品推荐

