SwiftUI实现左下角起始的1-100棋盘式网格问题求助
解决方案
你的代码存在两个核心问题:
- 使用
reversed()反转数字顺序后,未处理行起始颜色的交替逻辑 - 仅通过数字奇偶判断颜色,忽略了棋盘布局中每行起始颜色随行数变化的规则
以下是调整后的代码,完全匹配你预期的布局:
import SwiftUI struct LevelOverviewView: View { let numberOfLevels = 100 let columns = 4 var body: some View { ScrollView { LazyVGrid(columns: Array(repeating: GridItem(.fixed(70)), count: columns), content: { // 从最后一行开始遍历到第一行,实现左下角起始的布局 ForEach((0..<(numberOfLevels / columns)).reversed(), id: \.self) { rowIndex in let startNumber = rowIndex * columns + 1 // 遍历当前行的所有数字 ForEach(startNumber..<startNumber + columns, id: \.self) { number in ZStack { Rectangle() .fill(getBackgroundColor(for: number, rowIndex: rowIndex)) .aspectRatio(1.0, contentMode: .fit) Text("\(number)") .foregroundStyle(getTextColor(for: number, rowIndex: rowIndex)) } } } // 处理总数不是列数倍数的剩余数字 if let remaining = numberOfLevels % columns, remaining > 0 { let lastRowIndex = numberOfLevels / columns let startNumber = lastRowIndex * columns + 1 ForEach(startNumber..<startNumber + remaining, id: \.self) { number in ZStack { Rectangle() .fill(getBackgroundColor(for: number, rowIndex: lastRowIndex)) .aspectRatio(1.0, contentMode: .fit) Text("\(number)") .foregroundStyle(getTextColor(for: number, rowIndex: lastRowIndex)) } } } }) } .background(.red) } // 结合行索引和列索引判断背景色 private func getBackgroundColor(for number: Int, rowIndex: Int) -> Color { let columnIndex = (number - 1) % columns // 从下往上数,偶数行起始为黑,奇数行起始为白,交替填充 return (rowIndex % 2 == 0 && columnIndex % 2 == 0) || (rowIndex % 2 == 1 && columnIndex % 2 == 1) ? .black : .white } // 根据背景色返回反色文字 private func getTextColor(for number: Int, rowIndex: Int) -> Color { getBackgroundColor(for: number, rowIndex: rowIndex) == .black ? .white : .black } } #Preview { LevelOverviewView() }
关键调整说明:
- 行顺序控制:通过反转行索引,让包含1-4的最下方行优先渲染,实现从左下角开始的布局
- 颜色逻辑修正:同时参考行索引和列索引判断颜色,确保每行起始颜色交替,符合棋盘规则
- 边界兼容:增加了对总数非列数倍数的情况处理,保证最后一行剩余数字的正确显示
内容的提问来源于stack exchange,提问作者Trailblazer
相关产品推荐
相关产品推荐

