Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

SwiftUI alert view not showing up when TableRow context menu button is clicked

I try to show an alert view when user is going to delete a selected table-row. The delete button is part of a table-row context menu. I think this is because table-row is not a view but when moving the alert to the table view I cannot access secretItem from the ForEach loop anymore. So how to delete rows (object items) from a table with alert views on context menu buttons

Any guidance for me?

struct SecretDetailView: View {
  @State private var showDeleteAlert = false

  var table: some View {
    Table(selection: $selection, sortOrder: $sortOrder) {
        TableColumn("User Name", value: \.userName)
        ...
  } rows: {
        ForEach(secretItems) { secretItem in
            TableRow(secretItem)
                // Menue showing up with right click on table row for row manipulation
                .contextMenu {
                    Button("Delete Item") {
                        showDeleteAlert.toggle()
                    }
                    // alert not showing up here:
                    .alert(isPresented: $showDeleteAlert) {
                        Alert(
                            title: Text("Do you want to delete item?"),
                            message: Text(""),
                            primaryButton: .cancel(
                                Text("Cancel"),
                                action: { }
                            ),
                            secondaryButton: .destructive(
                                Text("Delete"),
                                action: {deleteSelectedSecretItem(secretItem) }
                            )
                        )
                    }
                }
        }

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

Use the alert overloads that takes in a value to be presented, such as alert(_:isPresented:presenting:actions:) or alert(item:content:) (deprecated in iOS 17). This way, you can move the alert modifier to be on the Table instead.

Add a new @State to store the item to be deleted, and set this in the context menu "Delete" button’s action.

// assuming secretItems is an array of "Item"
@State private var toBeDeletedItem: Item?
.contextMenu {
    Button("Delete Item") {
        showDeleteAlert.toggle()
        toBeDeletedItem = item
    }
}
// add this to the Table
.alert("Do you want to delete item?", isPresented: $showDeleteAlert, presenting: toBeDeletedItem) { item in
    Button("Delete", role: .destructive) {
        deleteSelectedSecretItem(item)
    }

    Button("Cancel", role: .cancel) { }
}

Or if you are on an earlier version and alert(_:isPresented:presenting:actions:) is not available:

.alert(item: $toBeDeletedItem) { item in
    Alert(
        title: Text("Do you want to delete item?"),
        message: Text(""),
        primaryButton: .cancel(
            Text("Cancel"),
            action: { }
        ),
        secondaryButton: .destructive(
            Text("Delete"),
            action: { deleteSelectedSecretItem(item) }
        )
    )
}
// You don't actually need showDeleteAlert!
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading