SwiftUI:取消查看导致索引超出范围错误
这件事让我毛骨悚然,我希望有人能告诉我哪里出了问题 目标是我需要能够管理项目的动态列表(即列表可以增长或收缩),其中每个项目的属性都可以调整(编辑),并且项目与给定的父项相关 在下面的简略代码中,我调用了item单元格,它属于一行。一行可以有许多单元格,每个单元格都有用户可以更改的数量。这是我的代码的一个节略版本,我希望它能让关系标签更清晰一些,但关键的是,它给了我同样的错误,那就是: 如果单元格数量小于原始数量(即,在本例中为3或更少),则每当关闭视图时,应用程序都会因“索引超出范围”错误而崩溃。到目前为止,可以添加或删除单元格而不会出现任何问题,并且在更改单元格项的数量时,我不会出现此错误。我浏览了很多博客,没有找到任何人遇到过这个问题——似乎大多数索引超出范围的帖子都是在实际修改列表时出现的,我的错误只发生在列表缩小后被驳回时 我在下面附上了一些示例代码-您应该能够剪切/粘贴并试用 我知道calculateTotals()是草图;请不要在总数中添加字母或标点符号-这只是为了测试绑定是否正确冒泡:) 单元格SwiftUI:取消查看导致索引超出范围错误,swiftui,swiftui-list,Swiftui,Swiftui List,这件事让我毛骨悚然,我希望有人能告诉我哪里出了问题 目标是我需要能够管理项目的动态列表(即列表可以增长或收缩),其中每个项目的属性都可以调整(编辑),并且项目与给定的父项相关 在下面的简略代码中,我调用了item单元格,它属于一行。一行可以有许多单元格,每个单元格都有用户可以更改的数量。这是我的代码的一个节略版本,我希望它能让关系标签更清晰一些,但关键的是,它给了我同样的错误,那就是: 如果单元格数量小于原始数量(即,在本例中为3或更少),则每当关闭视图时,应用程序都会因“索引超出范围”错误而崩
struct Cell: Identifiable {
var amount: String
var id = UUID()
init(_ amount: String = "0.00"){
self.amount = amount
}
}
行
class Row: ObservableObject {
@Published var cells: [Cell]
init(){
self.cells = [
Cell("10"),
Cell("15"),
Cell("20"),
Cell("25")]
}
}
struct ContentView: View {
@State private var displayAmounts = false
var body: some View {
NavigationView {
Button(action: {
self.displayAmounts.toggle()
}) {
Text("View amounts")
}
}
.sheet(isPresented: self.$displayAmounts) {
CellSheet()
}
}
}
ContentView
class Row: ObservableObject {
@Published var cells: [Cell]
init(){
self.cells = [
Cell("10"),
Cell("15"),
Cell("20"),
Cell("25")]
}
}
struct ContentView: View {
@State private var displayAmounts = false
var body: some View {
NavigationView {
Button(action: {
self.displayAmounts.toggle()
}) {
Text("View amounts")
}
}
.sheet(isPresented: self.$displayAmounts) {
CellSheet()
}
}
}
单元格页
struct CellSheet: View {
@ObservedObject var row: Row = Row()
private func deleteCell(at offsets: IndexSet) {
self.row.cells.remove(atOffsets: offsets)
}
private func calculateTotals() -> String {
var total = Double("0.00")!
for cell in self.row.cells {
if( "" != cell.amount ) {
total += Double(cell.amount)!
}
}
return String("\(total)")
}
var body: some View {
VStack{
List {
ForEach(row.cells.indices, id: \.self){ i in
CellItem(amount: self.$row.cells[i].amount)
}.onDelete(perform: deleteCell)
}
Button(action: {
self.row.cells.append(Cell())
}) {
Text("Add new cell")
}
Text(calculateTotals())
}
}
}
CellItem-这里有些奇怪:如果我用HStack包装文本字段,那么如果删除单元格,应用程序会立即崩溃——即使单元格总数大于原始数量(4)
我真的不知道这是怎么发生的。很明显,Swift试图访问一个不存在的索引(如果我删除绑定并只输出值,那就没有问题),但我不明白为什么在视图被取消时会出现问题。我猜斯威夫特在内存中缓存一些东西?HStack包装问题也很特殊
无论如何,我对斯威夫特还比较陌生,所以我可能忽略了一些显而易见的东西。另外,我运行的是XCode 11.4.1,目标是iOS 13.4
您应该能够将所有这些代码直接提升到一个新项目中,它将被编译。任何帮助都会得到感激:)好的,在创建这篇文章几分钟后(我已经做了几天),我想我有一个解决方案。我在ContentView中修改了列表(),如下所示:
List {
ForEach(Array(row.cells.enumerated()), id:\.1.id) { (i, cell) in
CellItem(amount: self.$row.cells[i].amount)
}.onDelete(perform: deleteCell)
}
这是基于我认为(?)枚举()更适合数组长度可变的情况。通过上述实现,HStack崩溃也得到了解决。也许有人可以给这篇文章添加更多的内容。好的,在写了这篇文章几分钟后(我已经写了几天),我想我有了一个解决方案。我在ContentView中修改了列表(),如下所示:
List {
ForEach(Array(row.cells.enumerated()), id:\.1.id) { (i, cell) in
CellItem(amount: self.$row.cells[i].amount)
}.onDelete(perform: deleteCell)
}
这是基于我认为(?)枚举()更适合数组长度可变的情况。通过上述实现,HStack崩溃也得到了解决。也许有人可以给它添加更多的上下文。让我充满希望-当它是数组中的最后一项时崩溃会返回。让我充满希望-当它是数组中的最后一项时崩溃会返回。