How can I add a confirmation to my deleteRow()
function? A already added the .alert
but I don't know how to continue.
List {
ForEach(data, id: \.self) { item in
Text(item)
.alert(isPresented: self.$showingDeleteAlert) {
Alert(title: Text("..."), message: Text("..."), primaryButton: .destructive(Text("Delete")) {
deleteRow // ???
}, secondaryButton: .cancel()
)
}
}
.onDelete(perform: deleteRow)
}
func deleteRow(at indexSet: IndexSet) {
for index in indexSet {
let item = data[index]
viewContext.delete(item)
do {
try viewContext.save()
} catch let error {
print("Error: \(error)")
}
}
}
``
Here is possible approach:
@State private var toBeDeleted: IndexSet?
...
List {
ForEach(data, id: \.self) { item in
Text(item)
.alert(isPresented: self.$showingDeleteAlert) {
Alert(title: Text("..."), message: Text("..."), primaryButton: .destructive(Text("Delete")) {
for index in self.toBeDeleted {
let item = data[index]
viewContext.delete(item)
do {
try viewContext.save()
} catch let error {
print("Error: \(error)")
}
}
self.toBeDeleted = nil
}, secondaryButton: .cancel() {
self.toBeDeleted = nil
}
)
}
}
.onDelete(perform: deleteRow)
}
func deleteRow(at indexSet: IndexSet) {
self.toBeDeleted = indexSet // store rows for delete
self.showingDeleteAlert = true
}
In iOS 15+ you can use swipe actions and confirmationDialog
@State private var showingDeleteAlert = false
List {
ForEach(data, id: \.self) { item in
Text(item)
.swipeActions {
Button("Delete", role: .destructive) {
showingDeleteAlert = true
}
}
.confirmationDialog(
Text("..."),
isPresented: $showingDeleteAlert,
titleVisibility: .visible
) {
Button("Delete", role: .destructive) {
withAnimation {
deleteItem(item)
}
}
}
}
func deleteItem(_ item: NSManagedObject) {
viewContext.delete(item)
do {
try viewContext.save()
} catch let error {
print("Error: \(error)")
}
}
}
Continuing the answer by @vadian and the comments to his answer, this code works for me with minimal glitching. Basically, move the confirmation dialog to a lower level, but in order to keep the reference to the item being deleted, add a @State var to track it.
Note: The reason I say "minimal glitching", is that when you complete the swipe to delete, the row does actually disappear and instantly reappears in the same spot. It's almost imperceptible without using slow animations in the simulator. But it's the least glitchy solution I've found so far. If anyone can figure out a way to have it perfect, I'm all ears.
@State private var showingDeleteAlert = false
@State private var itemToDelete: Item? = nil
List {
ForEach(data, id: \.self) { item in
Text(item)
.swipeActions {
Button("Delete", role: .destructive) {
self.itemToDelete = item
showingDeleteAlert = true
}
}
}
.confirmationDialog(
Text("..."),
isPresented: $showingDeleteAlert,
titleVisibility: .visible
) {
Button("Delete", role: .destructive) {
withAnimation {
deleteItem(itemToDelete)
}
}
}
func deleteItem(_ item: NSManagedObject?) {
guard let item else { return }
viewContext.delete(item)
do {
try viewContext.save()
} catch let error {
print("Error: \(error)")
}
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.