@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 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.
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.
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.
@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.
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.
@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.
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.
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.
@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.
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
@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.
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.
@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.
@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.
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
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.
Lesen Sie auch