Ein erster Blick auf SwiftUI (WWDC 2019 Preview) – Teil 5

Buttons und Binding

In diesem Teil der Artikelreihe zu SwiftUI setzen wir uns mit zwei Elementen auseinander. Zum einen werfen wir einen Blick auf die Structure Button, mit deren Hilfe man – wer hätte es gedacht? 😉 – Schaltflächen in eigenen Views einbinden kann. Zum anderen betrachten wir in diesem Zuge eine besondere Form des Data Binding in SwiftUI. Die benötigen wir, um Eigenschaften unserer Views dynamisch zur Laufzeit zu verändern.

Button implementieren

Los geht‘s mit der Erstellung einer einfachen View. Die verfügt über zwei Elemente: einen Text und einen Button. Das Besondere: Der Text soll abhängig vom Wert der Property useLargeFont als Titel oder als Standardtext formatiert werden. Die Property ist Teil der zugrundeliegenden View und besitzt den Standardwert false. Bei Betätigen des Buttons soll dieser Wert invertiert und das Erscheinungsbild des Textes entsprechend aktualisiert werden.

Text und Button werden in einem VStack arrangiert. Welche Textformatierung zum Einsatz kommt, wird über eine If-Abfrage geregelt.

Der Initializer der Button-Structure erwartet zwei Closure-Parameter. Der erste definiert die Aktion, die auszuführen ist, wenn der Button betätigt wird. Im zweiten Closure definiert man das Aussehen des Buttons. Dazu nutzt man – ähnlich einem Stack – verschiedene View-Elemente. In dem gezeigten Beispiel kommt ein einfacher Text mit dem Titel „Change font“ zum Einsatz.

Das folgende Listing zeigt die Basiskonfiguration der View. Um die Action des Buttons kümmern wir uns gleich.

struct ContentView : View {
    
    var useLargeFont = false
    
    var body: some View {
        VStack {
            if useLargeFont {
                Text("Hallo SwiftUI!").font(.title)
            } else {
                Text("Hallo SwiftUI!")
            }
            Button(action: {
                // Zu implementierende Button-Action ...
            }) {
                Text("Change font")
            }
        }
    }
    
}

Generell ist die Aktion, die bei Betätigen des Buttons ausgeführt werden soll, simpel: Auf der useLargeFont-Property soll die Methode toggle() aufgerufen werden, um den Wert der Property zu invertieren und im Anschluss das Erscheinungsbild der View (oder genauer gesagt des Textes) zu aktualisieren.

Allerdings kann useLargeFont nicht einfach so geändert werden. Das hängt damit zusammen, dass alle in SwiftUI erstellten Views (wie hier unsere eigene ContentView) immutable und damit unveränderbar sind. Was also tun?

Auftritt von @State

Hier kommt ein neues Schlüsselwort namens @State ins Spiel. Damit kennzeichnet man eine Property einer View, die einen bestimmten Status widerspiegelt und essenziell für die Darstellung der View ist. In unserem Beispiel trifft genau das auf useLargeFont zu: Diese Property bestimmt maßgeblich, wie die kreierte View am Ende aussieht.

Mit @State deklarierte Properties sind typischerweise privat, da sie sich auf einen ganz speziellen Status beziehen, der ausschließlich für die zugrundeliegende View relevant ist (und somit nicht von außen gelesen und gesetzt werden sollte). Entsprechend ist es zwingend notwendig, ihnen einen Standardwert zuzuweisen, da durch eine Deklaration als Privat von außen niemand sonst einen passenden Wert setzen kann.

Das folgende Listing zeigt den aktualisierten Code. Zum einen wurde die useLargeFont-Property sowohl mit dem Schlüsselwort @State als auch als private deklariert (wobei letzteres in diesem Fall keinen Einfluss auf die korrekte Funktionsweise der View hat, dafür aber dem Best Practice entspricht). Und innerhalb des Button-Closures, das die Aktionen bei Betätigen der Schaltfläche steuert, wurde der Befehl zum Invertieren der useLargeFont-Property gesetzt.

struct ContentView : View {
    
    @State private var useLargeFont = true
    
    var body: some View {
        VStack {
            if useLargeFont {
                Text("Hallo SwiftUI!").font(.title)
            } else {
                Text("Hallo SwiftUI!")
            }
            Button(action: {
                self.useLargeFont.toggle()
            }) {
                Text("Change font")
            }
        }
    }
    
}

Führt man dieses Projekt nun aus, lässt sich durch Betätigen des Buttons das Erscheinungsbild des Textes im Wechsel ändern.

Durch Betätigen des Buttons ändert sich wechselnd die Formatierung des Textes.
Durch Betätigen des Buttons ändert sich wechselnd die Formatierung des Textes.

Fazit

Data Binding spielt in SwiftUI eine immens wichtige Rolle und basiert auf einer Vielzahl von Neuerungen, die zusammen mit SwiftUI von Apple eingeführt werden. Das Schlüsselwort @State ist eine dieser Neuerungen und für all jene Properties gedacht, die Einfluss auf das Erscheinungsbild einer View nehmen. Solche Properties werden auch als Source of Truth bezeichnet, eben weil sie elementar wichtig für die Darstellung einer View sind. Es gibt aber noch weitere Elemente, die als Source of Truth fungieren können; dazu ein andermal mehr.

Idealerweise sollte jede View maximal eine Source of Truth besitzen. Stellt man also fest, dass man in einer View mehr als eine @State-Property benötigt, sollte man möglicherweise darüber nachdenken, stattdessen mehrere kleine Views zu erstellen und diese am Ende ineinander zu verschachteln.

Euer Thomas


Kommentare

Schreibe einen Kommentar

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