SwiftUI: Alert

UIAlertController

Alert is the equivalent to UIKit’s UIAlertView in SwiftUI. This post is about creating and presenting an alert in SwiftUI.

Creating an alert in SwiftUI

Creating an alert in SwiftUI is very straight forward:

But how do you present it? Since SwiftUI is a declarative UI framework, you don’t present is by reacting to a user action in a callback. Instead, you declare under which state it should be presented. Remember: A SwiftUI view is a function of its state.

You define the conditions for presenting the alert by using the alert function. It takes two arguments:

  1. A bool binding (the state) that specifies whether the alert should be displayed.
  2. A closure that returns the actual alert.

SwiftUI refreshes the view whenever the bool value changes since it is a state. As a consequence, the alert gets displayed if it’s set to true. After the alert gets dismissed, the bool value is set automatically to false.

Take a look at the following example:

The alert has by default an “OK” button.

Of course it’s also possible to add a message by using the message parameter:

Adding buttons and actions

So the alert from the last example is quite appropriate for displaying a message. But in many cases you also want the user to take a decision and you want do define an action. For that, you can add one or two buttons that have completion blocks. An alert with one button can be created as following:

Besides default there are another two button types: destructive and cancel. You should pick the one that fits best to your action.

Now let’s add two buttons:

It’s not possible to add more than two buttons though. Although that’s possible in UIKit, that’s actually not a restriction in SwiftUI: Alerts with more than two buttons could be confusing. Instead, you can use an action sheet.

Creating multiple alerts in SwiftUI

So far so good. But for a view it’s not so uncommon to have more than one scenario for displaying an alert. So do you just chain the .alert functions? Let’s try it out:

Unfortunately, this doesn’t work. The reason is that every view can only have one alert. So one possibility is to call the alert function on the two button views:

This works. However, if you have several alerts, this can become quite confusing. Alternatively, you can use an overloaded method of .alert. Instead of a boolean it takes a binding that confirms to the Identifiable protocol. A type confirms to this protocol if it implements an id so that an instance can be identified uniquely. We create a struct that confirms to this protocol. Furthermore, this struct has an enum that represents all possible alert types:

Now whenever the value of alertId changes, the view gets refreshed (a SwiftUI view is a function of its state!) and displays the alert. To make the code a little bit more clear, we create the alert inside a helper function.

References

Image: @ schatzy /shutterstock.com