Search code examples
swiftswiftuialert

SwiftUI - Add delete action (with index) to Alert button


I have a DataManager in which I have the following delete func:

  func deleteValue(index: Int) {
        storage.remove(at: index)
        save()
    }

And then in another view I have all my values into a Form. I wouldn't like to use the .onDelete because I would like to have an Alert that lets the user decide if he/she really wants to delete the value, but by doing this I must insert the index. How do I do this? Here's the code:

@State var showAlertDelete = false

var dm : DataManager

var deleteButton : some View {
    Button(action: {
        showAlertDelete = true
    }) { Text("Delete").foregroundColor(Color.red)
    }.alert(isPresented: $showAlertDelete, content: {
        deleteValueAlert
    })
}

func deleteValue(at offset: IndexSet) {
    guard let newIndex = Array(offset).first else { return }
    dm.deleteValue(index: newIndex)
}

var deleteValueAlert : Alert {
    Alert(title: Text("Are you sure you want to delete this?"), primaryButton: Alert.Button.default(Text("Yes")){ deleteValue //Here it says that I must add the init with the index }, secondaryButton: Alert.Button.cancel(Text("No")))
}

How can I solve this? Thanks to everyone!


Solution

  • You can use .onDelete by also presenting an Alert when triggered, simply add:

    @State private var showAlert = false    
    @State private var indexSetToDelete: IndexSet?
    

    And then in your .onDelete method:

    .onDelete { (indexSet) in
         self.showAlert = true
         self.indexSetToDelete = indexSet
     }
    

    Last step would be to add the Alert in your view body where you can call your delete method:

    .alert(isPresented: $showAlert) {
        Alert(title: Text("Confirm Deletion"),
            message: Text("Are you sure you want to delete xxx?"),
            primaryButton: .destructive(Text("Delete")) {
               self.deleteValue(indexSet: self.indexSetToDelete!) //call delete method
            },
            secondaryButton: .cancel())
    }