SwiftUI Alert, ActionSheet, and Confirmation Dialogs

SwiftUI provides several ways to display alerts, action sheets, and confirmation dialogs to your users. These UI elements are crucial for communicating important information, requesting confirmation for actions, or offering choices to the user. Understanding how to implement and customize these elements is essential for creating a polished and user-friendly iOS application.

What are Alerts, Action Sheets, and Confirmation Dialogs?

  • Alerts: Display a brief, important message with an optional button to acknowledge. They’re suitable for errors, warnings, and simple notifications.
  • Action Sheets: Present a set of options to the user. These are typically used on iPad or when presenting options related to a specific action. In recent iOS versions, the presentation style leans toward using ConfirmationDialog (dialog on iPad) with a popover-like style for actions triggered within a view.
  • Confirmation Dialogs: Offer a set of actions related to the alert. Suitable for use on iPad. In iOS 15 and later on iPhone as well

Implementing Alerts in SwiftUI

Simple Alert

A basic alert typically contains a title and a dismiss button.

import SwiftUI

struct ContentView: View {
    @State private var showAlert = false

    var body: some View {
        Button("Show Alert") {
            showAlert = true
        }
        .alert(isPresented: $showAlert) {
            Alert(
                title: Text("Important message"),
                message: Text("This is a basic alert."),
                dismissButton: .default(Text("OK"))
            )
        }
    }
}

Alert with Multiple Buttons

Alerts can include multiple buttons, allowing users to perform actions directly from the alert.

import SwiftUI

struct ContentView: View {
    @State private var showAlert = false

    var body: some View {
        Button("Show Alert") {
            showAlert = true
        }
        .alert(isPresented: $showAlert) {
            Alert(
                title: Text("Confirmation"),
                message: Text("Are you sure you want to proceed?"),
                primaryButton: .destructive(Text("Delete")) {
                    // Handle deletion here
                    print("Item deleted")
                },
                secondaryButton: .cancel()
            )
        }
    }
}

Customizing Alert Buttons

You can customize the behavior of the alert buttons by providing closures that execute when the buttons are tapped.

import SwiftUI

struct ContentView: View {
    @State private var showAlert = false

    var body: some View {
        Button("Show Alert") {
            showAlert = true
        }
        .alert(isPresented: $showAlert) {
            Alert(
                title: Text("Error"),
                message: Text("An error occurred."),
                dismissButton: .default(Text("Retry")) {
                    // Handle retry action
                    print("Retrying...")
                }
            )
        }
    }
}

Implementing Action Sheets in SwiftUI

Simple Action Sheet

An action sheet provides a list of options for the user to choose from.

import SwiftUI

struct ContentView: View {
    @State private var showActionSheet = false

    var body: some View {
        Button("Show Action Sheet") {
            showActionSheet = true
        }
        .actionSheet(isPresented: $showActionSheet) {
            ActionSheet(
                title: Text("Choose an Option"),
                message: Text("Select one of the following options:"),
                buttons: [
                    .default(Text("Option 1")) {
                        // Handle Option 1
                        print("Option 1 selected")
                    },
                    .default(Text("Option 2")) {
                        // Handle Option 2
                        print("Option 2 selected")
                    },
                    .cancel()
                ]
            )
        }
    }
}

Note: actionSheet is deprecated from iOS 15 and later, confirmationDialog is preferred. Use actionSheet with older targets only

Action Sheet with Specific Actions

You can include specific actions such as destructive actions (e.g., deletion) in an action sheet.

import SwiftUI

struct ContentView: View {
    @State private var showActionSheet = false

    var body: some View {
        Button("Show Action Sheet") {
            showActionSheet = true
        }
        .actionSheet(isPresented: $showActionSheet) {
            ActionSheet(
                title: Text("Manage Item"),
                message: Text("Choose what you want to do with this item."),
                buttons: [
                    .destructive(Text("Delete")) {
                        // Handle delete action
                        print("Item deleted")
                    },
                    .default(Text("Share")) {
                        // Handle share action
                        print("Share tapped")
                    },
                    .cancel()
                ]
            )
        }
    }
}

Implementing Confirmation Dialogs in SwiftUI

The confirmationDialog modifier is a replacement of actionSheet to support multiple buttons (options). Unlike actionSheet, you provide the buttons inside a closure, so you do not have to create an ActionSheet.

Basic Confirmation Dialog

The minimal implementation specifies the title and then provide the set of actions that your user can perform.

import SwiftUI

struct ContentView: View {
    @State private var showConfirmationDialog = false
    @State private var selectedAction: String? = nil // To track selected action if needed

    var body: some View {
        VStack {
            Button("Show Confirmation Dialog") {
                showConfirmationDialog = true
            }
            .confirmationDialog(
                "Choose an Option",
                isPresented: $showConfirmationDialog,
                titleVisibility: .visible
            ) {
                Button("Option 1") {
                    selectedAction = "Option 1"
                    print("Option 1 tapped")
                }
                Button("Option 2") {
                    selectedAction = "Option 2"
                    print("Option 2 tapped")
                }
                Button("Cancel", role: .cancel) {
                    print("Cancel tapped")
                }
            } message: {
                Text("Select one of the available options:")
            }
        }
    }
}

In the above snippet, .confirmationDialog receives the title for the dialog, a binding that defines the showing of the dialog (isPresented) and, crucially, the view that comprises your set of options that you can render on the screen for your dialog (rendered in content argument of confirmationDialog`). The code defines that the buttons ‘Option 1’, ‘Option 2’ and ‘Cancel’ show as possible actions.

Using Roles in Confirmation Dialog

SwiftUI supports roles which semantically represent how the buttons operate (.destructive, .cancel). Applying the correct semantic to a view changes its presentation on-screen to show a sense of ‘destructiveness’ (i.e. makes text red on iOS) for that given role

import SwiftUI

struct ContentView: View {
    @State private var showConfirmationDialog = false
    @State private var selectedAction: String? = nil // To track selected action if needed

    var body: some View {
        VStack {
            Button("Show Confirmation Dialog") {
                showConfirmationDialog = true
            }
            .confirmationDialog(
                "Delete item?",
                isPresented: $showConfirmationDialog,
                titleVisibility: .visible
            ) {
                Button("Delete", role: .destructive) {
                    selectedAction = "Delete"
                    print("Delete tapped")
                }
                Button("Cancel", role: .cancel) {
                    print("Cancel tapped")
                }
            } message: {
                Text("Are you sure you want to delete this item?")
            }
        }
    }
}

Considerations for Accessibility

When implementing alerts, action sheets, and confirmation dialogs, consider the following accessibility guidelines:

  • Provide clear and concise titles and messages.
  • Ensure buttons are labeled clearly with descriptive text.
  • Use appropriate roles (e.g., .destructive, .cancel) for semantic meaning.
  • Test with VoiceOver to ensure a smooth user experience for visually impaired users.

Conclusion

Alerts, action sheets, and confirmation dialogs are crucial UI elements in iOS applications. SwiftUI provides a simple and efficient way to implement these components. By using alerts for important messages, action sheets and confirmation dialogs for multiple choices, and considering accessibility, you can create user-friendly applications that communicate effectively with your users.