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
必须是偶数。
我会通过始终检查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("")
【讨论】:
【参考方案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 网格索引超出范围的主要内容,如果未能解决你的问题,请参考以下文章