Animationen mit SwiftUI – Teil 3

Die withAnimation(_:_:)-Funktion

In den vorangegangenen Artikeln dieser Serie (siehe Linksammlung am Ende des Artikels) haben wir bereits die Animation-Structure sowie den animation(_:)-Modifier kennen gelernt. Beide Elemente ermöglichen es uns, eine SwiftUI-View mit einer Animation zu versehen. Diese Animation wird immer dann ausgelöst, wenn sich eine animierbare Eigenschaft der View ändert.

SwiftUI bietet aber noch eine zweite Möglichkeit, um Animationen in Views auszulösen. Statt auf View-Ebene (wie bei Einsatz des animation(_:)-Modifiers) findet diese zweite Option auf Status-Ebene statt. Doch was bedeutet das?

Mit dem animation(_:)-Modifier ist die Durchführung einer Animation fest an die zugehörige View gekoppelt. Sollen bei einer Statusänderung mehrere Views auf die gleiche Art und Weise animiert werden, müsste man so jede dieser Views mit dem animation(_:)-Modifier versehen.

Führt man jedoch die Animation auf Status-Ebene durch, werden automatisch alle Views animiert, die von einer Statusänderung betroffen sind. Zu diesem Zweck nutzt man die globale SwiftUI-Funktion withAnimation(_:_:). Sie erwartet wenigstens ein Closure, über das man beliebige Befehle ausführen kann. Kommt es bei dieser Befehlsausführung zu Änderungen, die sich auf animierbare Eigenschaften von Views beziehen, wird bei all diesen Views eine entsprechende Animation ausgelöst. Um welche Animation es sich handelt, legt man über den ersten Parameter der Funktion fest. Der erwartet – genau wie der animation(_:)-Modifier – zu diesem Zweck eine Animation-Instanz.

Um das Konzept der withAnimation(_:_:)-Funktion besser zu verstehen, findet ihr im folgenden Listing ein Beispiel dazu. Darin erfolgt die Deklaration einer View, die aus zwei Textansichten besteht. Beide besitzen eine Hintergrundfarbe, deren Wert über einen Status namens color gesteuert wird. Ein Button erlaubt die Änderung jenes Status.

struct ContentView: View {
    @State private var color = Color.blue
    
    var body: some View {
        VStack {
            Button("Change background color") {
                withAnimation(.linear) {
                    color = changeColor()
                }
            }
            Divider()
            Text("Some text with background color")
                .font(.title)
                .background(color)
            Text("Another text with background color")
                .font(.title)
                .background(color)
        }
    }
    
    private func changeColor() -> Color {
        color == .red ? .blue : .red
    }
}

Genau bei jener Änderung von color kommt die withAnimation(_:_:)-Funktion zum Einsatz. Die sorgt dafür, dass alle Views, die durch die Änderung von color animiert werden sollen, auch automatisch mit einer entsprechenden Animation versehen werden. Beide Textansichten erhalten so genau die Animation, die als erster Parameter der withAnimation(_:_:) Funktion übergeben wird (in diesem Fall handelt es sich um eine einfache lineare Animation).

Würde man in dem gezeigten Beispiel auf den animation(_:)-Modifier zurückgreifen, müsste man beide Text-Views damit versehen. Durch Einsatz von withAnimation(_:_:) und der Durchführung der Animation auf Status-Ebene spart man sich diese Dopplung.

Wenn ihr also Animationen in SwiftUI umsetzen möchtet, steht immer die Frage im Raum, ob ihr die Animation explizit an eine View oder übergreifend an einen Status koppelt. Abhängig davon nutzt ihr entweder den animation(_:)-Modifier (View-Ebene) oder die withAnimation(_:_:)-Funktion (Status-Ebene).

Euer Thomas

Weitere Artikel aus dieser Serie


Kommentare

Schreibe einen Kommentar

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