[英]SwiftUI .onDelete throws Fatal Error: Index out of range
I have list of Account
s that each of them has a detail page and they are connected through @Binding
in the AccountDetailView
.我有一个
Account
列表,它们每个都有一个详细信息页面,并且它们通过AccountDetailView
中的@Binding
连接。 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.但是,当我将
onDelete
修饰符添加到下面的ForEach
并尝试swipe to delete
应用程序中的手势时,它会崩溃并显示两次Fatal Error: Index out of range
。
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.我进行了一些搜索并了解到
ForEach
以某种方式没有得到通知 - 或者忽略它,idk 很多细节 - 并寻找数组的最后一个索引。 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)
}
}
}
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.将
id: \.self
参数保持在适当位置时,它会在AppDelegate
引发错误,当我尝试删除参数时,应用程序工作正常,但再次onDelete
它会在NavigationLink
上面的行中引发相同的错误。
Here is the AccountDetailView
这是
AccountDetailView
struct AccountDetailView: View {
@EnvironmentObject var accountsModel: AccountsViewModel
@Binding var account: Account
@State var isEditing: Bool = false
var body: some View {
...
}
}
Finally Account
class conforms to Codable
, NSObject
, Indentifiable
and some other class.最后
Account
class 符合Codable
、 NSObject
、 Indentifiable 和其他一些Indentifiable
。 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.
提前致谢。
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.显然,使用
.indices
ForEach
会使onDelete
不起作用。 Instead, going through directly Elements
of an array and creating proxy Bindings
is working.相反,直接通过数组
Elements
并创建代理Bindings
是有效的。
To be it more clear here are the ContentView
, DetailView
and an extension for Binding
to avoid cluttering view.这里更清楚的是
ContentView
, DetailView
和Binding
的扩展以避免混乱的视图。
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())
}
}
Binding
extension Binding
扩展
extension Binding where Value: MyData {
init(from data: MyData) {
self.init(get: {
data as! Value
}) {
dataStore.data[dataStore.data.firstIndex(of: data)!] = $0
}
}
}
This way, both onDelete
and publishing changes by directly updating the object inside detail view will work.这样,通过直接更新 object 内部详细视图的
onDelete
和发布更改都将起作用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.