我想让单个单元格(centerCellView)跨越多个列和行,占据 5x4 网格中 6、7、8、11、12 和 13 号位置(2 行 x 3 列)。以下是当前布局的截图:
private func gridSection() -> some View {
let spacing: CGFloat = 10
let columns: [GridItem] = Array(repeating: GridItem(.flexible(), spacing: spacing), count: gridColumns)
return GeometryReader { geometry in
let totalSpacing = spacing * CGFloat(gridColumns - 1)
let cellSize = (geometry.size.width - totalSpacing - 20) / CGFloat(gridColumns)
Color("FFEA6D")
.onAppear {
gridCellSize = cellSize
}
LazyVGrid(columns: columns, spacing: spacing) {
ForEach(0..<(gridRows * gridColumns), id: \.self) { index in
if index == 6 {
centerCellView(size: cellSize)
.frame(width: cellSize * 3 + spacing * 2, height: cellSize * 2 + spacing)
.gridCellColumns(3)
.gridCellAnchor(.topLeading)
} else if [7, 8, 11, 12, 13].contains(index) {
EmptyView()
.frame(width: cellSize, height: cellSize)
} else {
normalCellView(size: cellSize)
}
}
}
.padding(.horizontal, 10)
.padding(.vertical, 20)
}
.frame(height: gridCellSize * CGFloat(gridRows) + spacing * CGFloat(gridRows - 1) + 40)
}
private func centerCellView(size: CGFloat) -> some View {
RoundedRectangle(cornerRadius: 20)
.fill(Color("FFEA6D"))
.stroke(isFlipped ? Color("12B754") : Color("FF403D"), lineWidth: 2)
.overlay(
Text(isFlipped ? "180.00¢" : "0.00¢")
.font(.system(size: 20, weight: .bold))
.foregroundColor(isFlipped ? Color("12B754") : Color("FF403D"))
)
}
private func normalCellView(size: CGFloat) -> some View {
Circle()
.stroke(isFlipped ? Color("12B754") : Color("FF403D"), lineWidth: 2)
.frame(width: size, height: size)
.overlay(
Image("generic_avatar")
.resizable()
.scaledToFill()
.foregroundColor(isFlipped ? Color("44BD86") : Color("FF8673"))
.frame(width: size * 0.9, height: size * 0.9)
.clipShape(Circle())
)
.rotation3DEffect(
.degrees(isFlipped ? 180 : 0),
axis: (x: 0.0, y: 1.0, z: 0.0),
perspective: 0.3
)
.animation(.spring(response: 0.5, dampingFraction: 0.85), value: isFlipped)
}
在 SwiftUI 的 LazyVGrid 中实现单元格跨行跨列需要巧妙的布局策略,因为 LazyVGrid 本身不支持直接的跨行功能(仅支持跨列)。以下是基于最佳实践的解决方案: