SwiftUI in der Praxis – Teil 3

Alerts in SwiftUI

Mit der Structure Alert besitzt SwiftUI einen eigenen View-Typ, mit dem sich Nutzern Meldungen in einer App anzeigen lassen. Vergleichbar ist Alert mit dem UIAlertController aus dem UIKit-Framework, allerdings verfügt das SwiftUI-Pendant nur über einen kleinen Bruchteil von dessen Funktionen.

Einen einfachen Alert erstellen

Um einen ganz simplen Alert in SwiftUI zu erstellen braucht es nicht viel. Tatsächlich reicht der folgende Befehl vollkommen aus:

Alert(title: Text("Some alert"))

Über den title-Parameter des Alert-Initializers definiert ihr den Titel für die anzuzeigende Meldung (in diesem Fall also „Some alert“). Dieser Alert wird vom System automatisch mit einer „OK“-Schaltfläche ergänzt, die bei Betätigung den Alert wieder ausblendet.

Möchtet ihr neben einem Titel zusätzlich noch eine Mitteilung in eurem Alert ausgeben, ergänzt ihr dazu im Initializer den message-Parameter und übergibt ihm den gewünschten Text. Wichtig hierbei: Genau wie beim Titel erwartet auch message eine Instanz vom Typ Text:

Alert(title: Text("Some alert"), message: Text("The alert message."))

Buttons im Alert ergänzen

Oftmals soll ein Alert mit verschiedenen Aktionen verknüpft werden, die der Nutzer in Form von Buttons aufrufen kann. So kann ein Alert beispielsweise vor dem Löschen eines Objekts nachfragen, ob die Aktion tatsächlich durchgeführt werden soll. Bestätigt der Nutzer dies durch Auswahl des zugehörigen Buttons, beginnt der Löschvorgang.

Buttons in SwiftUI-Alerts basieren auf dem Typ Alert.Button. Button ist in diesem Fall also ein Nested Type von Alert.

Ein solcher Button setzt sich aus drei Eigenschaften zusammen:

  1. Die Art des Buttons. Die Auswahl bestimmt, wie der Button im Alert optisch dargestellt wird. Hierbei stehen euch die bereits vom UIAlertController bekannten Optionen cancel, default und destructive zur Verfügung.
  2. Der Titel des Buttons (in Form einer Text-Instanz).
  3. Die auszuführenden Aktionen bei Betätigen des Buttons. Diese Eigenschaft ist optional und kann weggelassen werden. In diesem Fall wird der Alert bei Betätigen des Buttons einfach ausgeblendet.

Die erste Eigenschaft definiert ihr durch Auswahl einer passenden Typmethode von Alert.Button. Die Methode cancel(_:action:) erzeugt einen Cancel-Button, default(_:action:) einen Default- und destructive(_:action:) einen Destructive-Button.

Den Titel des Buttons sowie die optional auszuführenden Aktionen erwarten die genannten Methoden als Parameter. Lediglich für einen Cancel-Button steht eine weitere Typmethode namens cancel(_:) zur Verfügung, die nur die auszuführenden Aktionen und keinen Titel erwartet. Hierbei wird ein Standardtext für den Titel des Buttons verwendet.

Im folgenden Listing seht ihr einige Beispiele zum Erzeugen von Alert-Buttons:

// Cancel-Button (without action)
let simpleCancelButton = Alert.Button.cancel()
let customCancelButton = Alert.Button.cancel(Text("Dismiss"))

// Default-Button (without action)
let defaultButton = Alert.Button.default(Text("Default"))

// Destructive-Button
let destructiveButton = Alert.Button.destructive(Text("Destructive")) {
    print("Do something destructive ...")
}

Buttons einem Alert zuweisen

Alerts in SwiftUI können aktuell maximal zwei Buttons besitzen. Die übergibt ihr bei Initialisierung eines Alerts über die beiden Parameter primaryButton und secondaryButton, wie im folgenden Befehl zu sehen:

Alert(title: Text("Some alert"), message: Text("The alert message."), primaryButton: simpleCancelButton, secondaryButton: destructiveButton)

Falls ihr nur einen Button zum Ausblenden des Alerts anzeigen wollt (und den möglicherweise zusätzlich mit eigenen Aktionen verknüpft), könnt ihr alternativ statt primaryButton und secondaryButton auch den Parameter dismissButton verwenden:

Alert(title: Text("Some alert"), message: Text("The alert message."), dismissButton: simpleCancelButton)

Alert einblenden

Bleibt abschließend noch eine Frage zu klären: Wie blendet man einen so erstellten Alert in SwiftUI überhaupt ein?

Basis hierfür ist unter anderem der Modifier alert(isPresented:content:). Den verknüpft man mit der View, über die der gewünschte Alert eingeblendet werden soll. Über den content-Parameter (bei dem es sich um ein Closure handelt) gibt man die anzuzeigende Alert-Instanz zurück.

Der erste Parameter – isPresented – entspricht einem Binding vom Typ Bool. Hier übergebt ihr einen Status über den ihr steuert, ob der Alert sichtbar ist oder nicht. Sobald ihr diesen Status auf true setzt, erscheint der Alert. Das könnt ihr beispielsweise durch Betätigen eines Buttons steuern.

Ein vollständiges Beispiel, dass das Erstellen und Einblenden eines Alerts in SwiftUI zeigt, findet ihr im folgenden Listing. Darin steuert die State-Property showsAlert die Sichtbarkeit eines Alerts. Durch Betätigen eines Buttons wird dieser Status geändert, was zum Einblenden des Alerts führt.

struct ContentView: View {
    @State private var showsAlert = false
    
    var body: some View {
        Button(action: {
            self.showsAlert.toggle()
        }) {
            Text("Show alert")
        }
        .alert(isPresented: $showsAlert) {
            let simpleCancelButton = Alert.Button.cancel()
            let destructiveButton = Alert.Button.destructive(Text("Destructive")) {
                print("Do something destructive ...")
            }
            return Alert(title: Text("Some alert"), message: Text("The alert message."), primaryButton: simpleCancelButton, secondaryButton: destructiveButton)
        }
    }
}

Fazit

Alerts werden – wie so ziemlich alles in SwiftUI – über einen Status gesteuert. Der bestimmt darüber, ob der Alert sichtbar ist oder nicht. Der Alert selbst wird mithilfe des Typs Alert erzeugt und lässt sich mit bis zu zwei Aktions-Buttons versehen. Damit ist Alert aktuell noch deutlich eingeschränkter im Vergleich zum UIAlertController aus dem UIKit-Framework, lässt sich aber mindestens ebenso einfach und komfortabel nutzen.

Euer Thomas

Bisherige Artikel in dieser Serie


Kommentare

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert