SwiftUI 网格索引超出范围

Posted

技术标签:

【中文标题】SwiftUI 网格索引超出范围【英文标题】:SwiftUI Grid Index out of Range 【发布时间】: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 张卡片,当你'正在尝试将第二张卡(不存在)放入您的最后一行。 是的,没错。你有解决办法吗? 【参考方案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)] ?? "-")
                    
//...

【讨论】:

以上是关于SwiftUI 网格索引超出范围的主要内容,如果未能解决你的问题,请参考以下文章

SwiftUI - 索引超出范围

索引超出范围的 SwiftUI 问题

SwiftUI:JSON 索引总是超出范围

索引超出范围 SwiftUI

表单中的 SwiftUI 选择器 - 索引超出范围

SwiftUI:从 ForEach 中删除项目导致索引超出范围