SwiftUI .onDelete 抛出致命错误:索引超出范围 [英] SwiftUI .onDelete throws Fatal Error: Index out of range
问题描述
我有 Account
的列表,每个列表都有一个详细信息页面,它们通过 AccountDetailView
中的 @Binding
连接.当前代码运行良好,更新很好.完全没有问题.但是,当我将 onDelete
修饰符添加到下面的 ForEach
并在应用程序中尝试 swipe to delete
手势时,它崩溃并显示 Fatal Error: 索引超出范围
两次.
I have list of Account
s that each of them has a detail page and they are connected through @Binding
in the AccountDetailView
. Current code work well, updates are fine. No problem at all. However when I added the onDelete
modifier to the ForEach
below and tried swipe to delete
gesture in app, it crashes and says Fatal Error: Index out of range
twice.
我进行了一些搜索并了解到 ForEach
以某种方式没有得到通知 - 或忽略它,发现很多细节 - 并查找数组的最后一个索引.最后,它找不到它并抛出错误.
I made some search and learned that ForEach
somehow does not get notified -or ignores it, idk much detail- and looks for the last index of the array. In the end, it can not find it and throws the error.
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
上面的行中抛出相同的错误.
With keeping id: \.self
parameter in place it throws the error at the AppDelegate
, when I try to remove the parameter, the app works fine but again onDelete
it throws the same error at NavigationLink
's row above.
这是AccountDetailView
struct AccountDetailView: View {
@EnvironmentObject var accountsModel: AccountsViewModel
@Binding var account: Account
@State var isEditing: Bool = false
var body: some View {
...
}
}
最后Account
类符合Codable
、NSObject
、Indentifiable
和其他一些类.我不想仅仅因为不想让问题变得复杂和难以检查而给出所有代码.如果需要,我将提供代码的任何部分.提前致谢.
Finally Account
class conforms to Codable
, NSObject
, Indentifiable
and some other class. I did not want to give all the code just because did not want make the question complicated and hard to examine. If requested, I will provide any part of the code. Thanks in advance.
推荐答案
找到了解决方案.关于这个 answer 相关问题,很清楚.显然,使用 .indices
来填充 ForEach
会使 onDelete
不起作用.相反,直接通过数组的 Elements
并创建代理 Bindings
是有效的.
Found a solution. With respect to the this answer to a related question, it came clear. Apperantly, with using the .indices
to fullfill ForEach
makes onDelete
not to work. Instead, going through directly Elements
of an array and creating proxy Bindings
is working.
为了更清楚,这里是 ContentView
、DetailView
和 Binding
的扩展以避免混乱的视图.
To be it more clear here are the ContentView
, DetailView
and an extension for Binding
to avoid cluttering view.
ContentView
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")
}
}
}
DetailView
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
}
}
}
这样,onDelete
和通过直接更新详细信息视图内的对象来发布更改都将起作用.
This way, both onDelete
and publishing changes by directly updating the object inside detail view will work.
这篇关于SwiftUI .onDelete 抛出致命错误:索引超出范围的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!