swift - SwiftUI .onDelete 抛出致命错误:索引超出范围
问题描述
我有一个 s 列表,它们每个都有一个详细信息页面,Account
并且它们通过@Binding
. AccountDetailView
当前代码运行良好,更新很好。完全没有问题。但是,当我将onDelete
修饰符添加到ForEach
下面并在应用程序中尝试swipe to delete
手势时,它会崩溃并说Fatal Error: Index out of range
两次。
我进行了一些搜索并了解到ForEach
不知何故没有得到通知 - 或者忽略它,idk 很多细节 - 并寻找数组的最后一个索引。最后,它找不到它并抛出错误。
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
struct AccountDetailView: View {
@EnvironmentObject var accountsModel: AccountsViewModel
@Binding var account: Account
@State var isEditing: Bool = false
var body: some View {
...
}
}
finallyAccount
类符合Codable
,NSObject
和Indentifiable
其他一些类。我不想仅仅因为不想让问题变得复杂且难以检查而给出所有代码。如果需要,我将提供代码的任何部分。提前致谢。
解决方案
找到了解决方案。关于对相关问题的这个答案,它很清楚。显然,使用.indices
to ForEach
fullfillonDelete
无法正常工作。相反,直接Elements
通过数组并创建代理Bindings
是有效的。
这里更清楚的是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 where Value: MyData {
init(from data: MyData) {
self.init(get: {
data as! Value
}) {
dataStore.data[dataStore.data.firstIndex(of: data)!] = $0
}
}
}
这样,onDelete
通过直接更新详细视图中的对象来发布更改和发布更改都将起作用。
推荐阅读
- bluetooth-lowenergy - 为什么android BLE会自动发送连接参数更新请求?
- azure-logic-apps - 如果无法使用设计器,如何在 Azure 门户中获取 HTTP 触发的逻辑应用的完整 URL?
- php - foreach 循环执行一次或执行每一轮
- angular - 在角度 9 中选择下拉更改传递模式
- excel - VBA 中的 Trim 函数问题(VBAtrim 后 Excel 更改数据)
- angular - Angular 8 和 Typescript 3.8 问题
- reactjs - 反应图表js跳过零值月
- html - 将文本移入
元素 - android - Xamarin Android 调用 WebAPI 连接失败
- python-3.x - 如何将输出显示为仅包含单词而不包含计数的列表?