从数组中删除 - 致命错误:索引超出范围 - SwiftUI 绑定

Posted

技术标签:

【中文标题】从数组中删除 - 致命错误:索引超出范围 - SwiftUI 绑定【英文标题】:Removing from array - Fatal error: Index out of range - SwiftUI Binding 【发布时间】:2020-07-07 17:16:11 【问题描述】:

我正在努力了解 SwiftUI 绑定。在这里,我在视图中显示一个数组并将值绑定到第二个视图。在第二个视图中,我从数组中删除数据。

但是我得到以下信息,

致命错误:索引超出范围

我没有收到self.person.notes.remove(at: self.index) 的错误,实际上这实际上是在删除数组中的注释。使用ForEach 时,它必须在第一个视图中,因为数组已被修改,现在它超出了范围。但我不确定如何解决这个问题?当然Binding 应该已经解决了这个问题。

查看 1

ForEach(self.person.notes.indices, id:\.self)  index in

   NoteView(person: self.$person, room: self.$home.notes[index], index: index)


查看 2

@Binding var person: Person
@Binding var note: Note
var index: Int

if self.index > 0 
       Button(action: 
             self.person.notes.remove(at: self.index)
       ) 
           Text("Remove")
       
 

知道这应该如何在 SwiftUI 中工作吗?

【问题讨论】:

***.com/a/63145650/1652402 是适合我的解决方案 【参考方案1】:

使用预先给定的索引进行删除总是有风险的。数据在后台更改的可能性等。在您尝试删除项目时获取索引以确保拥有正确的索引。以防数据在其他地方发生变化。 这应该可以帮助您理解:

struct ContentView: View 
    
    @State var myData: Array<String> = ["first", "second", "third"]
    
    var body: some View 
        ForEach(self.myData, id: \.self)  data in
            SecondView(myData: self.$myData, data: data)
        
    


struct SecondView: View 
    
    @Binding var myData: Array<String>
    // the data that is being tied to the view
    var data: String
    
    var body: some View 
        
        Button(action: 
            // calculate the index at the time of removal
            if let index = self.myData.firstIndex(of: self.data) 
                self.myData.remove(at: index)
            
        ) 
            Rectangle().foregroundColor(Color.red).frame(width: 100, height: 100).overlay(Text("Button \(self.data)"))
        
        
    


产生这个:

正如您提到的,您的错误在于第一个视图。这很可能是因为您正在使用索引数量构建 ForEach。当您删除一个时,ForEach 会遇到错误,因为它失去了对该项目的“跟踪”,并且具有 ForEach 提供的索引的项目不再存在。 试试这个:

ForEach(self.person.notes, id:\.self)  note in

   // Remove the index and calculate it on the second view as shown above. This then should solve the problem
   NoteView(person: self.$person, room: self.$home.notes)


【讨论】:

我没有收到'self.person.notes.remove(at:self.index)'的错误,实际上这实际上是删除了数组中的注释。使用 ForEach 时必须在第一个视图中,因为数组已被修改,现在超出范围 在这个答案中第一个视图如何不引用索引。这就是你需要做出的改变。 @Simon,可以通过显示带有所需更改的 OP 代码来改进您的答案。 我为这个问题添加了解释。我很抱歉没有直接回答。我通常倾向于给出如何解决问题的想法,而不仅仅是提供确切需要的代码。因为我认为理解而不是仅仅复制工作代码更重要。 @Simon 谢谢,我会接受这个答案,在你回答后我有点想通了;我只是被困在其他地方,忘记奖励对不起。 - 从使用索引更改代码时,添加列表时视图不再更新,因此我更进一步使用 ObservableObject 而不是状态和绑定,目前使用不同的管理状态方法测试不同的行为。 使用@State 时视图应该总是更新,并且它会改变。

以上是关于从数组中删除 - 致命错误:索引超出范围 - SwiftUI 绑定的主要内容,如果未能解决你的问题,请参考以下文章

在 ForEach 循环中删除项目会导致致命错误:索引超出范围

Swift 致命错误:数组索引超出范围

从firebase删除时数组索引超出范围

线程 1:致命错误:索引超出范围。没有快速从数组中获取值,控制台显示它们不是空数组

Swift,CollectionView,致命错误:索引超出范围

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