SwiftUI - 致命错误:从数组中删除元素时索引超出范围

Posted

技术标签:

【中文标题】SwiftUI - 致命错误:从数组中删除元素时索引超出范围【英文标题】:SwiftUI - Fatal error: index out of range on deleting element from an array 【发布时间】:2020-12-02 20:40:28 【问题描述】:

我在应用存储上有一个数组。我正在使用 foreach 方法显示其元素。它可以在数组的每个元素上滑动删除。但是当我删除一个时,应用程序崩溃了。这是我的第一个观点;

struct View1: View 

    @Binding var storedElements: [myElements]
    
    var body: some View
        GeometryReader 
            geometry in
        
        VStack
            ForEach(storedElements.indices, id: \.self)i in
                View2(storedElements: $storedElements[i], pic: $storedWElements[i].pic, allElements: $storedElements, index: i)
                
        .frame(width: geometry.size.width, height: geometry.size.height / 2, alignment: .top).padding(.top, 25)
        
    
    

然后查看2;

struct View2: View 
    
    @Binding var storedElements: myElements
    @Binding var pic: String
    @Binding var allElements: [myElements]
    var index: Int
    
    @State var offset: CGFloat = 0.0
    @State var isSwiped: Bool = false
    
    @AppStorage("pics", store: UserDefaults(suiteName: "group.com.some.id"))
    var arrayData: Data = Data()
    
    var body : some View 
            ZStack
                
                Color.red
                
                HStack
                    Spacer()
                    
                    Button(action: 
                        withAnimation(.easeIn)
                            delete()) 
                        Image(systemName: "trash").font(.title).foregroundColor(.white).frame(width: 90, height: 50)
                    
                
                View3(storedElements: $storedElements).background(Color.red).contentShape(Rectangle()).offset(x: self.offset).gesture(DragGesture().onChanged(onChanged(value:)).onEnded(onEnd(value:)))
            .frame(width: 300, height: 175).cornerRadius(30)
        
    
    func onChanged(value: DragGesture.Value) 
        
        if value.translation.width < 0 
            
            if self.isSwiped 
                self.offset = value.translation.width - 90
            else 
                self.offset = value.translation.width
            
        
    
    func onEnd(value: DragGesture.Value) 
        
        withAnimation(.easeOut) 
            if value.translation.width < 0 
                if -value.translation.width > UIScreen.main.bounds.width / 2 
                    self.offset = -100
                    delete()
                else if -self.offset > 50 
                    self.isSwiped = true
                    self.offset = -90
                else 
                    self.isSwiped = false
                    self.offset = 0
                
            else 
                self.isSwiped = false
                self.offset = 0
            
        
    
    
    func delete() 
        //self.allElements.remove(at: self.index)
        if let index = self.allElements.firstIndex(of: storedElements)  
            self.allElements.remove(at: index)
        
    

OnChange 和 onEnd 函数用于滑动。我认为它是导致崩溃的 foreach 方法。还尝试了删除功能的注释行,但没有帮助。 而且我知道它是一个很长的问题代码。我尝试了几天并在这里尝试了所有答案,但没有一个能解决我的问题。

【问题讨论】:

您的.onDelete 代码在哪里? @koen 哦,抱歉,已删除。我更新了问题 要滑动删除,你应该实现.onDelete。参见例如here。 我认为它用于列表。我早些时候尝试过,但它不允许我删除,菜单从未出现过 【参考方案1】:

在您的 myElements 类/结构中,确保它具有唯一的属性。如果不添加一个并在初始化时设置一个唯一的 ID

public class myElements 
  var uuid: String
  
  init() 
      self.uuid = NSUUID().uuidString
  

那么在删除元素的时候,而不是

if let index = self.allElements.firstIndex(of: storedElements)  
    self.allElements.remove(at: index)

使用

self.allElements.removeAll(where:  a in a.uuid == storedElements.uuid )

这是数组绑定安全的,因为它不使用索引

【讨论】:

我已经在 myElements 上有一个 id 属性,尝试了你的 removeAll 方法但仍然崩溃 确切的错误信息是什么?它是否指出了哪一行导致它崩溃? 它把我扔到“0_swift_runtime_on_report”。并说线程 1:致命错误:索引超出范围。 您是否尝试过省略 .indices 的“ForEach(storedElements, id: \.self)”?修改后索引不更新其范围:***.com/a/59007863/4661144

以上是关于SwiftUI - 致命错误:从数组中删除元素时索引超出范围的主要内容,如果未能解决你的问题,请参考以下文章

致命错误:索引超出范围,同时在 SwiftUI 的列表中从 Firebase 中删除项目

SwiftUI:从 ForEach 中删除项目导致索引超出范围

SwiftUI - 删除绑定数组中的元素会导致错误

从核心数据中删除/添加到核心数据后,带有列表的 SwiftUI TabView 不刷新

为啥我的 SwiftUI JSONDecoder 会出现致命错误?

使用 UIImage 从数组中删除索引