@State — Zweck und Verwendung in SwiftUI

Autor: IT Sectr Veröffentlicht: 2026-06-19 Lesezeit: 7 Min.

@State ist ein Property Wrapper in SwiftUI zur Verwaltung lokaler Zustände innerhalb einer einzelnen View. SwiftUI zeichnet die View automatisch neu, sobald sich eine @State-Eigenschaft ändert, wodurch die Oberfläche reaktiv wird, ohne manuelle Update-Aufrufe. Laut der Apple Developer Documentation (2025) wird @State für einfache Typen und Strukturen empfohlen, die zu einer einzelnen View gehören. @State ist der einfachste Weg, einer SwiftUI-Oberfläche Interaktivität hinzuzufügen.

Wichtige Punkte

  • @State — Property Wrapper für lokalen Zustand, der zu einer einzelnen View gehört
  • Automatische Aktualisierung — SwiftUI ruft body erneut auf, wenn sich eine @State-Eigenschaft ändert
  • Einfache Typen — @State funktioniert mit String, Int, Bool, enum und Structs
  • Nicht an Kind-Views übergeben — für Änderungen aus Kind-Komponenten @Binding verwenden
  • private — @State-Eigenschaften werden immer mit dem Modifizierer private deklariert

Was ist @State in SwiftUI?

@State ist ein in SwiftUI integrierter Property Wrapper, der es einer View ermöglicht, ihren eigenen Zustand zu speichern und zu verfolgen. Wenn sich ein @State-Wert ändert, zeichnet SwiftUI die View automatisch neu, indem die body-Eigenschaft erneut aufgerufen wird. Dies ist die Grundlage der reaktiven Programmierung in SwiftUI: Der Entwickler deklariert den Zustand, und das Framework übernimmt die Synchronisation der Oberfläche.

@State erstellt einen Speicherbereich auf dem Heap, der von SwiftUI verwaltet wird. Dieser Bereich ist persistent — er überlebt wiederholte Initialisierungen der View-Struktur, die bei jeder Darstellung erfolgen. SwiftUI verwendet die Kennung der View (generiert aus ihrer Position in der Hierarchie), um die @State-Eigenschaft an eine bestimmte View zu binden. Dadurch wird der Zustand nicht zurückgesetzt, wenn die übergeordnete View aktualisiert wird.

Eine wichtige Einschränkung: @State ist nur für Wertetypen (Structs, Enums, Primitive) gedacht. Für Referenztypen (Klassen) verwenden Sie @StateObject oder @ObservedObject. Wenn Sie einer @State-Eigenschaft eine Klasse zuweisen, kann SwiftUI keine Änderungen innerhalb des Objekts erkennen — nur einen vollständigen Referenzaustausch.

Wie funktioniert @State unter der Haube?

SwiftUI implementiert @State über einen internen Storage-Mechanismus. Jede @State-Eigenschaft erhält eine dedizierte Speicherzelle, die in einem speziellen Speichercontainer der View gespeichert wird. Wenn ein Schreibvorgang in wrappedValue erfolgt, benachrichtigt SwiftUI über didSet seinen Abhängigkeitsgraphen über die Notwendigkeit einer Neuzeichnung.

swift
struct ContentView: View {
    @State private var name: String = "User"
    @State private var isLoggedIn: Bool = false

    var body: some View {
        VStack {
            Text("Hallo, \(name)")
            Button(isLoggedIn ? "Abmelden" : "Anmelden") {
                isLoggedIn.toggle()
            }
        }
    }
}

Im Beispiel gibt es zwei @State-Eigenschaften: name (String) und isLoggedIn (Bool). Wenn isLoggedIn.toggle() aufgerufen wird, markiert SwiftUI ContentView als aktualisierungsbedürftig und ruft body im nächsten Darstellungszyklus erneut auf. Der entscheidende Punkt: @State-Eigenschaften werden immer mit dem Modifizierer private deklariert — dies signalisiert, dass der Zustand ausschließlich der aktuellen View gehört und nicht von außen direkt geändert werden sollte.

Zur Beobachtung von Änderungen verwendet SwiftUI CurrentValueSubject aus Combine. Jede @State-Eigenschaft erstellt einen versteckten Publisher, der das System bei jeder Änderung benachrichtigt. Dadurch kann SwiftUI nur die minimal notwendige Menge an Views neu zeichnen und vollständige Hierarchieaktualisierungen vermeiden.

Wann @State in einem Projekt verwenden

@State ist optimal für einfache lokale Zustände: Textfelder in der Suche, boolesche Flags für modale Fenster, Einstellungsumschalter, Zähler, ausgewählte Listenelemente. Wenn ein Wert nur in einer View und ihren Kind-Komponenten (über @Binding) verwendet wird, ist @State die richtige Wahl. Für Zustände, die das Schließen der View überdauern sollen (z.B. Formulardaten), funktioniert @State ebenfalls, solange die View in der Hierarchie bleibt.

  • Textfelder — @State zum Speichern von eingegebenem Text in TextField
  • Boolesche Flags — @State zum Ein-/Ausblenden von modalen Fenstern und Sheets
  • Elementauswahl — @State zum Verfolgen des ausgewählten Tabs oder der Zeile
  • Zähler — @State für numerische Werte mit Inkrement/Dekrement
  • Zwischenberechnungen — @State zum Zwischenspeichern von Ergebnissen innerhalb einer View

Verwenden Sie @State nicht für globale Anwendungszustände, das Zwischenspeichern von Netzwerkdaten oder Objekte, die über mehrere Bildschirme hinweg verwendet werden. @StateObject und @EnvironmentObject sind für diese Zwecke konzipiert. Außerdem ist @State nicht geeignet für die Speicherung großer Datenmengen — jede Änderung führt zur Neuzeichnung der gesamten View.

@State und @Binding: Zusammenarbeit

@Binding ist eine Brücke zwischen @State in einer übergeordneten View und einer Kind-View, die diesen Zustand ändern muss. Der Elternteil deklariert @State, und die Kind-Komponente erhält ein Binding über die $-Projektion. Die Änderung des Bindings in der Kind-View aktualisiert automatisch das @State im Elternteil — und umgekehrt. Dies gewährleistet einen unidirektionalen Datenfluss mit Rückkopplungsmöglichkeit.

swift
struct ParentView: View {
    @State private var text: String = ""

    var body: some View {
        ChildView(text: $text)
    }
}

struct ChildView: View {
    @Binding var text: String

    var body: some View {
        TextField("Enter text", text: $text)
    }
}

Im Listing besitzt ParentView das @State text, und ChildView erhält $text als Binding. Das TextField innerhalb von ChildView bindet sich über text: $text an dieses Binding. Wenn der Benutzer in das TextField tippt, ändert sich der Wert in ChildView über das Binding, was eine Aktualisierung von @State in ParentView auslöst. Beide Views werden mit dem neuen Wert neu gezeichnet.

Häufige Fehler bei der Arbeit mit @State

Der häufigste Fehler ist die Zuweisung einer Klasse zu einer @State-Eigenschaft. Wenn Sie @State var model = MyClass() schreiben, kann SwiftUI keine Änderungen an Eigenschaften innerhalb der Klasse verfolgen — nur den Objektersatz. Für Klassen verwenden Sie immer @StateObject. Das zweite häufige Problem ist die Deklaration von @State ohne den Modifizierer private, was das Prinzip der Zustandskapselung verletzt.

Direkte Übergabe von @State an eine Kind-View ohne $ ist ein weiterer typischer Fehler. Wenn Sie TextField(text: text) anstelle von TextField(text: $text) übergeben, erhält die Kind-Komponente nur einen String, kein Binding. Textänderungen im TextField werden nicht mit dem @State des Elternteils synchronisiert. Verwenden Sie immer die $-Projektion, um Binding zu übergeben.

Der dritte Fehler sind mehrere @State-Eigenschaften für zusammenhängende Daten. Wenn mehrere Werte logisch eine Einheit bilden (z.B. Formularfelder), fassen Sie sie in einer einzigen Struktur mit einem einzigen @State zusammen. Dies vereinfacht die Übergabe des Zustands an Kind-Views und reduziert die Anzahl einzelner Aktualisierungsauslöser.

Beispiele für die Verwendung von @State in SwiftUI

@State wird in den meisten SwiftUI-Projekten für grundlegende Interaktivität verwendet. Betrachten wir ein Beispiel eines Anmeldeformulars, bei dem @State Textfelder und den Ladezustand verwaltet. Dieses Muster kommt in jeder Anwendung vor — von einfachen Notizen bis hin zu komplexen Unternehmenslösungen.

swift
struct LoginView: View {
    @State private var email: String = ""
    @State private var password: String = ""
    @State private var isLoading: Bool = false
    @State private var errorMessage: String?

    var body: some View {
        Form {
            TextField("Email", text: $email)
            SecureField("Password", text: $password)
            Button("Anmelden") {
                login()
            }.disabled(isLoading)
        }
    }

    private func login() {
        isLoading = true
        // Netzwerkanfrage ausführen
    }
}

Im Beispiel gibt es vier @State-Eigenschaften: email und password für die Formularfelder, isLoading für die Ladeanzeige und errorMessage für die Fehleranzeige. Jede Eigenschaft verwaltet unabhängig ihren Teil der Oberfläche. Wenn sich isLoading ändert, wird die Schaltfläche automatisch über disabled(isLoading) deaktiviert — ohne manuelles UI-Update.

Häufig gestellte Fragen

Warum wird @State mit private deklariert?

@State ist für den lokalen Zustand einer bestimmten View konzipiert. Der Modifizierer private stellt sicher, dass andere Komponenten ihn nicht direkt ändern können, was die Kapselung brechen würde. Für externen Zugriff verwenden Sie die $-Projektion.

Kann @State ein Array oder Dictionary enthalten?

Ja, @State unterstützt Arrays und Dictionaries, da es sich um Wertetypen handelt. Wenn jedoch ein Element eines Arrays geändert wird, zeichnet SwiftUI die gesamte View neu. Für große Listen ist @StateObject mit @Published effizienter.

Was passiert, wenn nil an eine @State-Eigenschaft mit Optional-Typ zugewiesen wird?

@State funktioniert korrekt mit Optional-Typen. Bei Zuweisung von nil erkennt SwiftUI die Änderung und zeichnet die View neu. Dies ist praktisch für Zustände wie errorMessage: String?, wo nil bedeutet, dass kein Fehler vorliegt.

Wie verhält sich @State, wenn die View erneut angezeigt wird?

@State behält den Wert, solange die View in der Hierarchie bleibt. Wenn die View aus der Hierarchie entfernt und wieder hinzugefügt wird, wird @State mit dem Standardwert neu initialisiert. Für Persistenz verwenden Sie @AppStorage.

Können @State-Änderungen animiert werden?

Ja, umschließen Sie die Änderung mit withAnimation: withAnimation(.easeInOut) { isExpanded.toggle() }. SwiftUI animiert den Übergang zwischen dem alten und neuen Zustand der Oberfläche mit dem angegebenen Animationstyp.

Zusammenfassung

  • @State — Property Wrapper für lokalen Zustand einer einzelnen View, aktualisiert automatisch die Oberfläche
  • Funktioniert mit einfachen Typen: String, Int, Bool, sowie Structs und Enums
  • Funktioniert nicht mit Referenztypen (Klassen) — @StateObject verwenden
  • Immer private — Zustand sollte nicht von außen direkt geändert werden
  • $-Projektion — erstellt ein Binding zur Übergabe von Änderungsrechten an Kind-Views
  • Mehrere @State in einer View — normale Praxis für unabhängige Zustände
  • withAnimation — ermöglicht die Animation von Änderungen an @State-Eigenschaften

Wir entwickeln eine mobile Applikation schlüsselfertig

IT Sectr entwickelt seit 2017 iOS- und Android-Apps für Startups und Unternehmen. Wir beraten Sie und schlagen die beste Lösung vor.

Projekt besprechen

Lesen Sie auch