SwiftUI .onDelete 抛出致命错误:索引超出范围
Posted
技术标签:
【中文标题】SwiftUI .onDelete 抛出致命错误:索引超出范围【英文标题】:SwiftUI .onDelete throws Fatal Error: Index out of range 【发布时间】:2020-05-07 22:11:31 【问题描述】:我有Account
s 的列表,它们每个都有一个详细信息页面,它们通过AccountDetailView
中的@Binding
连接。当前代码运行良好,更新很好。完全没有问题。但是,当我将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
...
最终Account
类符合Codable
、NSObject
、Indentifiable
和其他一些类。我不想仅仅因为不想让问题变得复杂且难以检查而给出所有代码。如果需要,我将提供代码的任何部分。提前致谢。
【问题讨论】:
【参考方案1】:找到了解决办法。关于这个answer 到一个相关问题,它很清楚。显然,使用.indices
填充ForEach
会使onDelete
不起作用。相反,直接通过数组的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
和通过直接更新详细视图中的对象来发布更改都将起作用。
【讨论】:
以上是关于SwiftUI .onDelete 抛出致命错误:索引超出范围的主要内容,如果未能解决你的问题,请参考以下文章
SwiftUI .onDelete 从 ForEach 获取 var