Swift onDelete抛出致命错误:索引超出范围
我有一个帐户列表,每个帐户都有一个详细页面,它们通过AccountDetailView中的@Binding连接。当前代码运行良好,更新良好。没问题。然而,当我将onDelete修改器添加到下面的ForEach并尝试在应用程序中滑动以删除手势时,它崩溃并显示致命错误:索引超出范围两次 我做了一些搜索,了解到ForEach不知何故没有得到通知——或者忽略了它,idk提供了很多细节——而是查找数组的最后一个索引。最后,它找不到它并抛出错误Swift onDelete抛出致命错误:索引超出范围,swift,swiftui,swiftui-list,swiftui-navigationlink,Swift,Swiftui,Swiftui List,Swiftui Navigationlink,我有一个帐户列表,每个帐户都有一个详细页面,它们通过AccountDetailView中的@Binding连接。当前代码运行良好,更新良好。没问题。然而,当我将onDelete修改器添加到下面的ForEach并尝试在应用程序中滑动以删除手势时,它崩溃并显示致命错误:索引超出范围两次 我做了一些搜索,了解到ForEach不知何故没有得到通知——或者忽略了它,idk提供了很多细节——而是查找数组的最后一个索引。最后,它找不到它并抛出错误 List { Section(header: Text
List {
Section(header: Text(String.empty), footer: Text(Strings.SectionFooters.accountListFooter.value)) {
ForEach(self.accountsModel.accounts.indices, id:\.self) { idx in
NavigationLink(destination: AccountDetailView(account: self.$accountsModel.accounts[idx])) {
AccountRow(account: self.$accountsModel.accounts[idx])
}
}.onDelete { (set) in
self.accountsModel.accounts.remove(atOffsets: set)
}
}
}
保留id:\.self参数后,它会在AppDelegate中抛出错误,当我尝试删除该参数时,应用程序工作正常,但再次onDelete时,它会在上面NavigationLink的行中抛出相同的错误
这是AccountDetailView
最后,Account类符合Codable、NSObject、Identifiable和其他一些类。我不想给出所有的代码,只是因为我不想让问题变得复杂和难以检查。如果要求,我将提供代码的任何部分。提前感谢。找到了解决方案。关于这一问题与一个相关问题的关系,已经很清楚了。显然,使用.index来填充ForEach会使onDelete不起作用。相反,直接遍历数组元素并创建代理绑定是可行的 更清楚的是,这里有ContentView、DetailView和绑定扩展,以避免视图混乱 内容视图 详细视图 绑定扩展
extension Binding where Value: MyData {
init(from data: MyData) {
self.init(get: {
data as! Value
}) {
dataStore.data[dataStore.data.firstIndex(of: data)!] = $0
}
}
}
这样,通过直接更新局部视图中的对象来执行onDelete和发布更改都会起作用
struct ContentView: View {
@EnvironmentObject var store: DataStore
var body: some View {
NavigationView {
List {
ForEach(self.store.data, id: \.id /*with or without id*/) { (data) in
NavigationLink(destination: DetailView(data: /*created custom initializer*/ Binding(from: data))) {
Text(data.name)
}
}.onDelete { (set) in
self.store.data.remove(atOffsets: set)
}
}.navigationBarTitle("List")
}
}
}
struct DetailView: View {
@Binding var data: MyData
var body: some View {
List {
TextField("name", text: self.$data.name)
}
.navigationBarTitle(self.data.name)
.listStyle(GroupedListStyle())
}
}
extension Binding where Value: MyData {
init(from data: MyData) {
self.init(get: {
data as! Value
}) {
dataStore.data[dataStore.data.firstIndex(of: data)!] = $0
}
}
}