SwiftUI 网格索引超出范围
SwiftUI Grid Index out of Range
我尝试 使用网格布局。
我们想在网格中动态显示数组项,如果 Array.count 更改出现索引超出范围的错误并且应用程序崩溃。
如何解决这个问题?
var totalrows: Int{
let t = Double(self.cards.count) / Double(self.cols)
return Int(round(t))
}
var cols: Int{
let col = self.verticalSizeClass == .compact ? 4 : 2
return col
}
func colrow (col: Int , row: Int) -> Int{
var colrow = 0
colrow = (row * self.cols) + col
return colrow
}
let cards = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M"]
var body: some View {
VStack{
ForEach(0..<self.totalrows,id:\.self) { row in
HStack {
ForEach(0..<self.cols,id:\.self) { column in
Text(self.cards[self.colrow(col: column, row: row)])
}
}
}
}
}
按照你 cols
return 4 或 2 的方式,你必须在 cards
中有一个偶数 count
。
我会通过始终检查 cards
的 count
并在末尾添加一个空项目来解决这个问题。
示例:
//only even numbers count
var cards = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M"]
if (cards.count % 2) != 0 {
cards.add("")
}
避免任何 indexOutOfBounds 的简单方法是在执行操作之前检查索引是否超出范围...
因此进行此更改:
ForEach(0..<self.cols,id:\.self) { column in
let card = self.colrow(col: column, row: row)
if (card < self.cards.count) {
Text(self.cards[card])
}
}
这将使您的最后一行可能未填充,但它不应崩溃
如果您添加自定义安全下标,您将能够使用 nil 合并将 boudns 数组元素的索引替换为您喜欢的任何内容。
extension Array {
subscript(guarded idx: Int) -> Element? {
guard (startIndex..<endIndex).contains(idx) else { return nil }
return self[idx]
}
}
然后您可以像这样重写 Text
视图以显示无效索引的连字符并且没有崩溃。
//...
ForEach(0..<self.cols,id:\.self) { column in
Text(self.cards[guarded: self.colrow(col: column, row: row)] ?? "-")
}
//...
我尝试
我们想在网格中动态显示数组项,如果 Array.count 更改出现索引超出范围的错误并且应用程序崩溃。
如何解决这个问题?
var totalrows: Int{
let t = Double(self.cards.count) / Double(self.cols)
return Int(round(t))
}
var cols: Int{
let col = self.verticalSizeClass == .compact ? 4 : 2
return col
}
func colrow (col: Int , row: Int) -> Int{
var colrow = 0
colrow = (row * self.cols) + col
return colrow
}
let cards = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M"]
var body: some View {
VStack{
ForEach(0..<self.totalrows,id:\.self) { row in
HStack {
ForEach(0..<self.cols,id:\.self) { column in
Text(self.cards[self.colrow(col: column, row: row)])
}
}
}
}
}
按照你 cols
return 4 或 2 的方式,你必须在 cards
中有一个偶数 count
。
我会通过始终检查 cards
的 count
并在末尾添加一个空项目来解决这个问题。
示例:
//only even numbers count
var cards = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M"]
if (cards.count % 2) != 0 {
cards.add("")
}
避免任何 indexOutOfBounds 的简单方法是在执行操作之前检查索引是否超出范围...
因此进行此更改:
ForEach(0..<self.cols,id:\.self) { column in
let card = self.colrow(col: column, row: row)
if (card < self.cards.count) {
Text(self.cards[card])
}
}
这将使您的最后一行可能未填充,但它不应崩溃
如果您添加自定义安全下标,您将能够使用 nil 合并将 boudns 数组元素的索引替换为您喜欢的任何内容。
extension Array {
subscript(guarded idx: Int) -> Element? {
guard (startIndex..<endIndex).contains(idx) else { return nil }
return self[idx]
}
}
然后您可以像这样重写 Text
视图以显示无效索引的连字符并且没有崩溃。
//...
ForEach(0..<self.cols,id:\.self) { column in
Text(self.cards[guarded: self.colrow(col: column, row: row)] ?? "-")
}
//...