删除对象导致索引超出范围

huangapple go评论76阅读模式
英文:

Deleting object causes index out of range

问题

我已经找到引起索引越界错误的原因,是这段代码:

if self.editMode.isEditing {
    TextField("Folder name", text: $folder.name)
        .textFieldStyle(RoundedBorderTextFieldStyle())
} else {
    Text(folder.name)
}

如果我将它删除,我就可以成功删除一个文件夹。所以我猜这与与文件夹的绑定有关?

英文:

I have a form with sections. I'm trying to delete a whole section but it's giving me index out of bounds error.

struct Folder: Identifiable {
    let id = UUID()
    
    
    var name: String
    var items: [Item]
}

struct Item: Identifiable {
    var id: String {
        name
    }
    
    let name: String
}

class FolderStore: ObservableObject {
    
    @Published var folders = ... // omitted for brevity
}


struct FoldersView: View {
    
    @ObservedObject var folderStore = FolderStore()
    @State private var editMode: EditMode = .inactive
    
    var body: some View {
        
        NavigationView {

            Form {
                                
                ForEach(folderStore.folders.indices) { index in
                    FolderView(editMode: self.$editMode, folder: self.$folderStore.folders[index])
                }
                
                
            }
            .navigationBarTitle("Folders")
            .navigationBarItems(leading:
                
                Group {
                    if !editMode.isEditing {
                        Button(action: {
                            self.editMode = .active
                            self.addFolder()
                        }) {
                            HStack {
                                Image(systemName: "plus.circle.fill")
                                Text("New Folder")
                            }
                        }
                    }
                }
                
            , trailing: EditButton())
            .environment(\.editMode, self.$editMode)
            .environmentObject(folderStore)
        }
    }
    
    private func addFolder() {
        let folder = Folder(name: "", items: [])
        folderStore.folders.insert(folder, at: 0)
    }
}


struct FolderView: View {
    
    @Binding var editMode: EditMode
    @EnvironmentObject var folderStore: FolderStore
    
    @Binding var folder: Folder
    
    var folderIndex: Int {
        folderStore.folders.firstIndex(where: { $0.id == folder.id })!
    }
    
    var body: some View {
        
        Section(header:
            HStack {
                              
                if self.editMode.isEditing {
                    TextField("Folder name", text: $folder.name)
                        .textFieldStyle(RoundedBorderTextFieldStyle())
                } else {
                    Text(folder.name)
                }
                                
                Spacer()
                
                if self.editMode.isEditing {
                    
                    Button(action: {
                        self.deleteFolder()
                    }) {
                        Text("Delete")
                    }
                }
            }
        ) {
                        
            ForEach(folder.items) { item in
                Text(item.name)
            }            
        }
    }
    
    private func deleteFolder() {
        folderStore.folders.remove(at: folderIndex)
    }
}

I nailed down what causes the index out of bounds and it's this code:

if self.editMode.isEditing {
      TextField("Folder name", text: $folder.name)
           .textFieldStyle(RoundedBorderTextFieldStyle())
} else {
      Text(folder.name)
}

If I remove it I can happily remove a folder. So I guess it has something to do with the binding with the folder?

答案1

得分: 0

成功地“修复”了它,很大程度上得益于这个问题的帮助。

我添加了这个:

/// 在删除后检查文件夹是否存在(否则将发生超出范围的索引)
private var folderExists: Bool {
    folderStore.folders.contains(folder)
}

每当我需要在我的内容中按索引引用folderStore时,我只需检查文件夹是否存在。

英文:

Managed to "fix" it much to the help from this question

I added this:

/// Check if folder exists after deletion (otherwise out of bounds index will occur)
    private var folderExists: Bool {
        folderStore.folders.contains(folder)
    }

And whenever I need to reference folderStore by index in my body I just check if folder exists.

huangapple
  • 本文由 发表于 2020年1月3日 20:46:40
  • 转载请务必保留本文链接:https://go.coder-hub.com/59578903.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定