Search code examples
ios14swiftui-list

onDelete: Accessing Data From Entry Before it is Deleted


When a user swipes to delete an entry in a list, isn't there a pointer that can be used to get information on the entry being deleted? Before the entry is deleted I want to know the category total. I'm having trouble with the function removeItems which is giving the error: Cannot convert value of type 'IndexSet' to expected argument type 'Int'

struct CatItem:  Codable, Identifiable {
    var id = UUID()
    var catNum: Int       
    var catName: String
    var catTotal: Double
    var catPix: String
    var catShow: Bool 
}

class Categories: ObservableObject {
    
    @Published var catItem: [CatItem] {
    didSet {
         }
     }
 } 





struct manCatView: View {
    
    @EnvironmentObject var userData: UserData
    @EnvironmentObject var categories: Categories
    
    var pic: String = ""
    
    var body: some View {
        
        List {
            ForEach(0 ..< categories.catItem.count) { index in
                if index.catShow == true {
                HStack {
                    let pic = categories.catItem[index].catPix
                    Image(systemName: pic)
                        .resizable()
                        
                        .foregroundColor(Color(colors[index]))
                        .frame(width: 40, height: 40)
                    
                    Text(categories.catItem[index].catName)
                    }
                }
            }
            .onDelete(perform: removeItems) 
        }
        .navigationBarTitle(Text("Manage Categories"), displayMode: .inline)
        NavigationLink(destination: addCatView()) {Text("Add Categories")
            .fontWeight(.bold)}
            .font(.title2)
            .disabled(categories.catItem.count > 16)
            
            .padding([.leading, .trailing], 10)
            .accentColor(Color(red: 60/255, green: 160/255, blue: 240/255))
        
        Text("")
        Text("")
        Text("Add Up to 5 Categories")
        Text("Swipe Left to Delete a Category")
        
        Rectangle()
            .frame(width: 50, height: 175)
            .foregroundColor(.white)
    }
    
    
    func removeItems(at offsets: IndexSet) {
        var catTotal: Double = 0.0
        
        //subtract entry amount from category total
        catTotal = categories.catItem[offsets].catTotal  // <-- need help with index here
        userData.totalArray[grandTotal] -= catTotal
        userData.totalArray[userTotal] -= catTotal
        
        
        categories.catItem.remove(atOffsets: offsets)
    }
}

Solution

  • IndexSet here is simple Set of Indexies, in simple case it will contain only one element (user delete entries one by one with swipe). So for simplicity you can use .first element for this. But better - to iterate through full set, it'll allow you more control.

    so code you need may look similar to this:

    func removeItems(at offsets: IndexSet) {
        var catTotal: Double = 0.0
        
        offsets.forEach { singleOffset in
            //subtract entry amount from category total
            catTotal = categories.catItem[singleOffset].catTotal
            userData.totalArray[grandTotal] -= catTotal
            userData.totalArray[userTotal] -= catTotal
        }
        
        categories.catItem.remove(atOffsets: offsets)
    }