Enhance UI/UX with the confirmation dialog component

Enhance UI/UX with the confirmation dialog component

Understand how to use confirmation dialogs within a SwiftUI app.

The confirmationDialog sheet is a SwiftUI component that presents a temporary dialog to confirm an action or provide a set of related options. It appears from the bottom of the screen and offers buttons for users to make a choice which can include destructive actions, multiple choices, or simply canceling the operation.

In the Apple ecosystem, it is used when you want to:

  1. Present the user with a set of options or a specific context;
  2. Confirm their intent before proceeding with an action that can be potentially destructive;
  3. Offering a way to cancel or back out of an action.
.confirmationDialog(
    // 1. The title of the Sheet
    "Title for the confirmation Dialog Sheet",
    
    // 2. The bool to enable the presentation of the sheet
    isPresented: $isPresented, 
    
    // 3. The visibility of the title
    titleVisibility: .visible, 
    
    // 4. Data to be presented
    presenting: dataToPresent
    
) { data in
    // 5. Buttons for different types of actions
    // a. A destructive action
    Button("Confirm", role: .destructive) {
        // Do something
    }
    // b. Different Options Actions
    Button("An action") {
        // Do something
    }
    Button("Another action") {
        // Do something
    }
    
    // c. Cancel the action
    Button("Cancel", role: .cancel) {
        isPresented = false
    }
}

The confirmationDialog(_:isPresented:titleVisibility:presenting:actions:) is a method that takes several parameters, which are:

  1. titleKey: a localized string to describe the title of the dialog;
  2. isPresented: a boolean value enabling the presentation of the dialog;
  3. titleVisibility: controls the visibility of the title. The default value is set as automatic and adapts based on platform and context, but can be overridden to visible or hidden accordingly to whether the title has to be always displayed or not;
  4. presenting: any type of data that has to be presented in the dialog and that can be manipulated;
  5. actions - the set of actions the user can choose from to perform:
    1. a destructive action like deleting data permanently;
    2. different actions with no prominent role;
    3. an action to dismiss the sheet without performing any action.

Let’s see how to integrate the confirmation dialog in a SwiftUI view.

import SwiftUI

struct DotsView: View {
    
    @State var isPresented: Bool = false
    @State var settingData: SettingData = .init(dotsTurnedOn: true, colorModality: .random)
    var body: some View {
        ZStack {
            Color.black
                .ignoresSafeArea()
            VStack(spacing: 0) {
                ForEach(0..<90) { row in
                    HStack(spacing: 2) {
                        ForEach(0..<40) { column in
                            LightingDot(settingData: $settingData)
                        }
                    }.offset(x: row%2 == 0 ? 0 : 7.5, y: 0)
                }
            }
            if settingData.dotsTurnedOn{
                Button {
                    isPresented.toggle()
                } label: {
                    Text("Change Color")
                }
                .buttonStyle(.borderedProminent)
                
                // The confirmation dialog
                .confirmationDialog("Are you sure you want to change color of the dots?", isPresented: $isPresented, titleVisibility: .visible, presenting: $settingData, actions: { action in
                    Button("Turn off the colors", role: .destructive){
                        settingData.dotsTurnedOn = false
                        settingData.colorModality = .off
                    }
                    Button("Random"){
                        settingData.colorModality = .random
                    }
                    Button("Pink"){
                        settingData.colorModality = .pink
                    }
                    Button("Teal"){
                        settingData.colorModality = .teal
                    }
                    Button("Yellow"){
                        settingData.colorModality = .yellow
                    }
                    Button ("Cancel", role: .cancel){
                        isPresented = false
                    }
                    Button ("Cancel", role: .cancel){
                    isPresented = false
                    }
                }).padding(.top, 600)
          
            } else {
                Text("The dots are off and cannot be turned on again.")
                    .foregroundStyle(.white)
            }
        }
    }
}

struct LightingDot: View {
    @Binding var settingData: SettingData
    @State private var isFlashing: Bool = false
    var body: some View{
        Circle()
            .fill(settingData.color)
            .frame(width: 15, height: 15)
            .opacity(self.isFlashing ? 0.8 : 0.3)
        
            .animation(settingData.dotsTurnedOn ? Animation.easeInOut(duration: Double.random(in: 0.5...1.5)).repeatForever(autoreverses: true) : nil, value: Double.random(in: 0.5...1.5))
            .onAppear {
                self.isFlashing = true
            }
    }
 }


struct SettingData{
    var dotsTurnedOn: Bool
    var colorModality: ColorModality
    
    enum ColorModality: String{
        case teal = "teal"
        case yellow = "yellow"
        case pink = "pink"
        case random = "random"
        case off = "off"
    }
    
    var color: Color {
        switch colorModality{
        case .teal: return Color.teal
        case .yellow: return Color.yellow
        case .pink: return Color.pink
        case .random: return [Color.teal, Color.yellow, Color.purple, Color.pink].randomElement()!
        case .off: return Color.clear
        }
    }
}
0:00
/0:21

In this sample view, the DotsView creates an interactive grid of animated, flashing dots changing their colors based on user preferences. Thanks to the confirmationDialog the user can select a color modality for the dots or turn them off.

It ensures that the user is presented with clear options when they want to change the color settings, while also guarding against unintended actions like turning off the dots permanently.


Using the confirmation dialog in SwiftUI improves both functionality and user experience.

In the example, by asking for user confirmation before performing potentially destructive actions, like turning off the dots permanently, the dialog prevents mistakes and ensures intentional interactions

The structured action options within the confirmation dialog allow users to easily make choices without feeling overwhelmed, adding clarity to the user journey and keeping the interface clean and focused.