SwiftUI: alert messages

By

Learn how to show a SwiftUI alert with .alert(), dismiss with OK, and add Cancel plus destructive Confirm actions when the user must choose.

~~~

A common way to give feedback to users, but also to help you debug your applications sometimes, is to use alerts.

SwiftUI provides the .alert() modifier that we can use to show an alert based on some condition.

Let’s start from this example where we have a Button with a counter:

import SwiftUI

struct ContentView: View {
    @State var count = 0
    
    var body: some View {
        Button("Count: \(count)") {
            self.count += 1
        }
        .font(.title)
    }
}

when count reaches 10 I want to show an alert message.

How do we do that?

I can add a showAlert boolean property to the ContentView and edit the content of the Button tap action:

struct ContentView: View {
    @State var count = 0
    @State var showAlert = false
    
    var body: some View {
        Button("Count: \(count)") {
            self.count += 1
            if self.count == 10 {
                showAlert = true
                self.count = 0
            }
        }
        .font(.title)
    }
}

When we reach 10, we set showAlert to true and we set the count to 0.

Then I add the .alert() modifier to the Button view:

.alert("Great!", isPresented: $showAlert) {
    Button("OK") { }
} message: {
    Text("You reached 10")
}

This alert is shown only when the showAlert property is true. When we dismiss the alert, the showAlert property is automatically set to false.

The title is the first argument, the buttons go in the first closure, and the text of the alert in the message: closure. When I first wrote this post the modifier was .alert(isPresented:) { Alert(title:message:) }. That form still compiles, but Apple deprecated it in iOS 15 in favor of this one.

Here’s the full code:

struct ContentView: View {
    @State var count = 0
    @State var showAlert = false
    
    var body: some View {
        Button("Count: \(count)") {
            self.count += 1
            if self.count == 10 {
                showAlert = true
                self.count = 0
            }
        }
        .font(.title)
        .alert("Great!", isPresented: $showAlert) {
            Button("OK") { }
        } message: {
            Text("You reached 10")
        }
    }
}

Try running the app. The counter starts at 0. Click the button and the counter will increase:

iPhone simulator showing a SwiftUI button displaying Count: 5

Until you reach 10:

iPhone simulator showing SwiftUI alert popup with title Great! You reached 10 and OK button

Then the counter will start again from 0:

iPhone simulator showing SwiftUI button with counter reset to Count: 0

Cancel and destructive actions

A single OK button is enough for “you reached 10”. When the user must choose, add more buttons in the actions closure. Use role: .cancel for Cancel and role: .destructive for a Confirm that deletes or resets something:

.alert("Delete item?", isPresented: $showDeleteAlert) {
    Button("Cancel", role: .cancel) { }
    Button("Confirm", role: .destructive) {
        // delete the item
    }
} message: {
    Text("This cannot be undone")
}

Tapping any button dismisses the alert. Cancel just closes it, Confirm runs your code first. The roles also change the look: Cancel gets its own slot, and a destructive button is drawn in red.

If you’d rather have the choices slide up from the bottom of the screen on iPhone instead of a centered box, use .confirmationDialog(). It has the same shape: a boolean binding and a closure with the buttons.

Tagged: Swift · All topics

Want me to talk about your product? You can sponsor this site.

~~~

Related posts about swift: