4. März 2020

Einführung in SwiftUI - Tutorial

Dieses SwiftUI-Tutorial vermittelt anhand einer Würfel-App die Grundlagen zur Oberflächenentwicklung mit SwiftUI.

Verwende für dieses Tutorial Xcode 11. Die Live-Vorschau funktioniert nur unter macOS Catalina, alle weiteren Funktionalitäten können auch unter Mojave verwendet werden (siehe Verwendung von SwiftUI unter Mojave).

  1. Erstelle mit File » New » Project... ⌘⇧N ein neues Xcode-Projekt Dice. Verwende die Vorlage Single View App und wähle als User Interface-Framework SwiftUI aus:

    Neues Xcode-Projekt anlegen
  2. Öffne die Datei ContentView.swift im Projekt und mache Dich mit dem erstellten Code vertraut.

    Es wurde ein struct-Typ ContentView erstellt, der konform zum View-Protokoll deklariert ist - in SwiftUI werden alle Views als Wertetyp konform zu dem View-Protokoll deklariert. Dieses Protokoll fordert die Eigenschaft body, die das View für die Anzeige „berechnet“:

    struct ContentView: View {
    
        var body: some View {
            Text("Hello World")
        }
    
    }
    

    Zusätzlich wird ein PreviewProvider für das View deklariert. Hier wird die Vorschau das Views in Xcode konfiguriert, z.B. könnte hier das View mit Beispieldaten befüllt werden (dieser Typ ist also nur zur Entwicklungszeit relevant):

    struct ContentView_Previews: PreviewProvider {
    
        static var previews: some View {
            ContentView()
        }
    
    }
    
  3. Blende die Canvas-Vorschau ein:

    Canvas-Vorschau für SwiftUI

    Aktiviere die Vorschau mit Resume (dies kann beim ersten Mal etwas dauern, da Xcode für die Live-Vorschau das Projekt bauen muss):

    Resume Canvas-Vorschau
  4. Ändere den Text im View - die Vorschau wird unmittelbar aktualisiert:

    Unmittelbare Aktualisierung der SwiftUI-Vorschau
  5. SwiftUI Views werden über Modifier angepasst. Setze dem Text eine Schriftfarbe und probiere dabei die verschiedenen Möglichkeiten aus, Modifier zu erzeugen:

    via -Klick im Code » Show SwiftUI Inspector…:

    SwiftUI-Inspektor via Code

    oder über -Klick in der Canvas-Vorschau:

    SwiftUI-Inspektor via Vorschau

    oder über den Attributes Inspector:

    SwiftUI-Attribute über Attributes-Inspektor berarbeiten
  6. Öffne die Library und ziehe einen neuen Button unterhalb des Labels:

    Button hinzufügen

    Der Editor wird automatisch ein gruppierendes VStack-Element erzeugen, welches Text-Label und Button übereinander stapelt:

    VStack {
        Text("Hallo SwiftUI")
        Button(action: {}) {
            Text("Button")
        }
    }
    
  7. Ändere den Button-Text zu „Würfeln“, vergib einen spacing-Abstand für den VStack und setze die Schrift für das Label als Large Title, so dass sich folgendes View ergibt:

    View mit veränderten Eigenschaften
  8. Deklariere eine Eigenschaft number, die die Würfelzahl enthält und erzeuge sofort eine Würfelzahl. Verwende diese für die Anzeige als Text:

    struct ContentView: View {
    
        var number = Int.random(in: 1...6)
    
        var body: some View {
            VStack(spacing: 20.0) {
                Text( String(number))
                    .font(.largeTitle)
                Button(action: {}) {
                    Text("Würfeln")
                }
            }
        }
    }
    
  9. Implementiere den action-Block des Buttons so, dass eine neue Würfelzahl generiert wird. Dies wird einen Compilerfehler auslösen: „Cannot assign to property: 'self' is immutable“:

    Cannot assign to property: 'self' is immutable

    Wertetypen in Swift sind standardmäßig unveränderbar (immutable) und können nur innerhalb von als mutating deklarierten Methoden verändert werden. Für SwiftUI wurde daher ein sog. Property Wrapper @State bereitgestellt, der veränderbaren Zustand (wie die Würfelzahl) innerhalb von SwiftUI-Views erlaubt.

    Jede Änderung einer @State-Eigenschaft bewirkt automatisch eine Aktualisierung des Views, indem die body-Eigenschaft erneut berechnet wird.

  10. Verwende @State für die number-Eigenschaft:

    struct ContentView: View {
    
        @State var number = Int.random(in: 1...6)
    
        var body: some View {
            VStack(spacing: 20.0) {
                Text(String(number))
                    .font(.largeTitle)
                Button(action: {
                    self.number = Int.random(in: 1...6)
                }) {
                    Text("Würfeln")
                }
            }
        }
    }
    
  11. Verwende die Live-Preview um eine interaktive Vorschau des Views zu testen:

  12. Tipp: Es gibt eine Variante von dem Button-Initializer, bei dem der action-Block als Trailing Closure übergeben wird. Vereinfache diese um den Button zu erzeugen:

    Button("Würfeln") {
        self.number = Int.random(in: 1...6)
    }
    
  13. Lade assets.zip herunter, das Bilder für das Projekt enthält, und entpacke das Archiv. Öffne Assets.xcassets im Xcode-Projekt und ziehe die Bilder für den Würfel in das Projekt:

    Drag folder dice into assets
  14. Füge dem View über die Media library per Drag&Drop ein Image mit einem der Würfel-Bilder hinzu (achte dabei darauf, dass das Image im VStack angelegt wird):

  15. Passe den Code so an, dass das Bild für die Würfelzahl gemäß number angezeigt wird und entferne das Text-Label. Du kannst \(...) verwenden, um den Wert in die Zeichenkette einzusetzen:

    struct ContentView: View {
    
        @State var number = Int.random(in: 1...6)
    
        var body: some View {
            VStack(spacing: 10.0) {
                Image("dice-\(number)")
                Button("Würfeln") {
                    self.number = Int.random(in: 1...6)
                }
            }
        }
    }
    
  16. Starte die App mit ⌘R im Simulator.