【问题标题】:SwiftUI Grid Index out of RangeSwiftUI 网格索引超出范围
【发布时间】:2020-01-07 17:26:51
【问题描述】:

我尝试this solution 使用网格布局。

我们希望在 Grid 中动态显示 Array Items,如果 Array.count Changed 出现 Index out of Range 错误并且应用程序崩溃。

如何解决这个问题?

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)])
                    }


                }
               }
    }
}

【问题讨论】:

  • 看起来你正试图在每行中放置 2 张卡片,如果有奇数张卡片,那么最后一行将只包含 1 张卡片,当你'正在尝试将第二张卡(不存在)放入您的最后一行。
  • 是的,没错。你有解决办法吗?

标签: swift swiftui swift5.2


【解决方案1】:

避免任何 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])
    }
}

这将使您的最后一行可能未填充,但它不应该崩溃

【讨论】:

    【解决方案2】:

    cols 返回 4 或 2 的方式是,cards 中的 count 必须是偶数。

    我会通过始终检查cardscount 并在末尾添加一个空项目(如果还没有的话)来解决这个问题。

    例子:

    //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("")
    }
    

    【讨论】:

      【解决方案3】:

      如果您添加自定义安全下标,您将能够使用 nil 合并将 index out 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)] ?? "-")
                          }
      //...
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多