NEW: Subscribe to Hacking with Swift+ and accelerate your learning! >>

Alert before onDelete list element

Forums > SwiftUI

I'm not able to trigger an Alert View from the onDelete closure, invoked deleting a list element, for example:

    private var viewUsers: some View {
        NavigationView {
            List {
                ForEach (self.usersViewModel.listOfUsers) {user in
                    VStack(alignment: .leading){
                        HStack {
                            Text(user.nomeUtente.capitalized).bold()
                            Text(user.cognomeUtente.capitalized).bold()
                        }
                        Text(user.mailUtente).foregroundColor(.gray)
                    }
                }
                .onDelete{ indexSet in
                    DispatchQueue.main.async() {
                        Alert(title: Text("title"), message: Text("message"), primaryButton: .default(Text("primaryButtonLabel")), secondaryButton: .cancel(Text("secondaryButtonLabel")))
                    }
                }
            }
            .navigationBarTitle(Text("Users"), displayMode: .inline)
            .navigationBarItems(trailing: EditButton())
        }
    }

Any suggestion ?

Thanks in advance.

   

Hi @giurobrossi, I think that a. views cannot be inserted via the .onDelete method in general (only logic) and b. that you need to introduce alerts through the .alert modifier, like so:

.alert(isPresented: $presentAlert) {
      Alert(...)
}

That would require you to introduce a presentAlert flag that is toggled to on in your .onDelete closure and toggled back off in the alert's handler.

   

That's fine, but the alert is shown after the execution of the onDelete callback: my purpose is to show the alert before the deletion of a list element. Unfortunately the indexSet of the deleting element is know only by the onDelete callback.

   

I'm using CoreData. The template for Master / Detail with CoreData has this in the Event.swift

extension Collection where Element == Event, Index == Int {
    func delete(at indices: IndexSet, from managedObjectContext: NSManagedObjectContext) {
        indices.forEach { managedObjectContext.delete(self[$0]) }
        do {
            try managedObjectContext.save()
        } catch {
            let nserror = error as NSError
            fatalError("Unresolved error \(nserror), \(nserror.userInfo)")
        }
    }
}

The content view has this:

ForEach(events, id: \.self) { event in
  NavigationLink(
    destination: DetailView(event: event)
  ) {
    Text("\(event.timestamp!, formatter: dateFormatter)")
    }
  }.onDelete { indices in
    self.events.delete(at: indices, from: self.viewContext)
  }

So I would think you can make your own function for deleting (a class function in User), and only go there if the user agrees from the alert. And put the alert in .onDelete like you did.

   

Hi @giurobrossi,

I've solved this issue (not having the indexSet after .onDelete is finished by having an

@State private var indexSetToDelete: IndexSet?

in my struct and setting this in the .onDelete:

@State private var showingAlert = false
@State private var deleteIndexSet: IndexSet?

<YOUR LIST>
.onDelete(perform: { indexSet in
    self.showingAlert = true
    self.deleteIndexSet = indexSet
})

.alert(isPresented: self.$showingAlert) {
    let indexSet = self.deleteIndexSet! /// you can force unwrap here because you only show the alert after .onDelete
    return Alert(<YOUR ALERT>)  /// do some stuff with the indexSet here
}

Hope that helps :)

(and I'm feeling great right now because this is the first time ever I shared my SwiftUI knowledge 🥰)

Greetings, Kevin

   

Hacking with Swift is sponsored by NSSpain

SPONSORED Announcing NSSpain 2020: Remote Edition! An online, continuous conference for iOS developers. We’ll start on Thursday and finish on Friday, with talks, activities, and lots of fun for 36 hours, non-stop. Sound good? Join us!

Find out more

Sponsor Hacking with Swift and reach the world's largest Swift community!

Reply to this topic…

You need to create an account or log in to reply.

All interactions here are governed by our code of conduct.

 
Unknown user

Not logged in

Log in
 

Link copied to your pasteboard.