@State — vad är det, syfte och användning i SwiftUI

Författare: IT Sectr Publicerad: 2026-06-19 Lästid: 7 min

@State är en Property Wrapper i SwiftUI för att hantera lokalt tillstånd inom en enda vy. SwiftUI ritar automatiskt om vyn vid varje ändring av @State-egenskapen, vilket gör gränssnittet reaktivt utan manella uppdateringsanrop. Enligt Apple Developer Documentation (2025) rekommenderas @State för enkla typer och strukturer som tillhör en enda vy. @State är det enklaste sättet att lägga till interaktivitet i ett SwiftUI-gränssnitt.

Huvudpunkter

  • @State — Property Wrapper för lokalt tillstånd som tillhör en vy
  • Automatisk uppdatering — SwiftUI startar om body vid ändring av @State-egenskap
  • Enkla typer — @State passar för String, Int, Bool, enum och strukturer
  • Skicka inte till kapslade vyer — för ändring från underordnade komponenter använd @Binding
  • private — @State-egenskaper deklareras alltid med private-modifieraren

Vad är @State i SwiftUI?

@State är en inbyggd Property Wrapper i SwiftUI som låter en vy lagra och övervaka sitt eget tillstånd. När värdet på @State ändras ritar SwiftUI automatiskt om vyn genom att anropa body-egenskapen igen. Detta är grunden för reaktiv programmering i SwiftUI: utvecklaren deklarerar tillståndet och ramverket tar hand om synkroniseringen av gränssnittet.

@State skapar ett lagringsområde på högen som hanteras av SwiftUI. Detta område är beständigt — det överlever upprepade initieringar av vystrukturen som sker vid varje rendering. SwiftUI använder vyidentifieraren (genererad baserat på position i hierarkin) för att binda @State-egenskapen till en specifik vy. Tack vare detta återställs inte tillståndet när den överordnade vyn uppdateras.

En viktig begränsning: @State är endast avsett för värdetyper (strukturer, uppräkningar, primitiver). För referenstyper (klasser) använd @StateObject eller @ObservedObject. Om du tilldelar en klass till en @State-egenskap kan SwiftUI inte upptäcka ändringar inuti objektet — endast ersättning av hela referensen.

Hur fungerar @State under huven?

SwiftUI implementerar @State genom den interna Storage-mekanismen. Varje @State-egenskap får en dedikerad minnescell som lagras i vyens speciella lagringscontainer. När en skrivning till wrappedValue sker, meddelar SwiftUI via didSet sin beroendegraf (dependency graph) om behovet av omritning.

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

    var body: some View {
        VStack {
            Text("Hej, \(name)")
            Button(isLoggedIn ? "Logga ut" : "Logga in") {
                isLoggedIn.toggle()
            }
        }
    }
}

I exemplet finns två @State-egenskaper: name (String) och isLoggedIn (Bool). Vid anrop av isLoggedIn.toggle() markerar SwiftUI ContentView som uppdateringsbehövande och startar om body i nästa renderingscykel. Nyckelpunkten: @State-egenskaper deklareras alltid med private-modifieraren — detta är en signal om att tillståndet uteslutande tillhör den aktuella vyn och inte bör ändras utifrån direkt.

För att observera ändringar använder SwiftUI CurrentValueSubject från Combine. Varje @State-egenskap skapar en dold utgivare som meddelar systemet vid varje ändring. Detta gör att SwiftUI bara kan rita om den minimalt nödvändiga uppsättningen vyer, vilket undviker fullständig uppdatering av hierarkin.

När ska man använda @State i projektet

@State är optimal för enkla lokala tillstånd: textfält för sökning, booleska flaggor för modala fönster, inställningsomkopplare, räknare, valda listelement. Om värdet endast används i en vy och dess kapslade komponenter (via @Binding), är @State rätt val. För tillstånd som bör överleva stängning av vyn (t.ex. formulärdata) är @State också lämpligt så länge vyn förblir i hierarkin.

  • Textfält — @State för att lagra inmatad text i TextField
  • Booleska flaggor — @State för att visa/dölja modala fönster och sheet
  • Elementval — @State för att spåra vald flik eller rad
  • Räknare — @State för numeriska värden med ökning/minskning
  • Mellanliggande beräkningar — @State för att cachelagra resultat inom vyn

Använd inte @State för globala applikationstillstånd, cachelagring av nätverksdata eller objekt som används på flera skärmar. För dessa ändamål är @StateObject och @EnvironmentObject avsedda. @State är inte heller lämpligt för lagring av stora datamängder — varje gång det ändras kommer hela vyn att ritas om.

@State och @Binding: samarbete

@Binding är en bro mellan @State i den överordnade vyn och den underordnade vyn som behöver ändra detta tillstånd. Föräldern deklarerar @State och den underordnade komponenten får Binding via $-projektionen. Ändring av Binding i den underordnade vyn uppdaterar automatiskt @State i föräldern — och vice versa. Detta säkerställer ett enkelriktat dataflöde med möjlighet till återkoppling.

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)
    }
}

I listningen har ParentView @State text, och ChildView får $text som Binding. TextField inuti ChildView binder till detta Binding via text: $text. När användaren skriver i TextField ändras värdet i ChildView via Binding, vilket orsakar uppdatering av @State i ParentView. Båda vyerna ritas om med det nya värdet.

Vanliga misstag vid arbete med @State

Det vanligaste misstaget — tilldelning av en klass till en @State-egenskap. Om du skriver @State var model = MyClass() kan SwiftUI inte spåra ändringar av egenskaper inuti klassen — endast ersättning av själva objektet. För klasser använd alltid @StateObject. Det andra vanliga problemet — deklarering av @State utan private-modifieraren, vilket bryter mot principen om tillståndsinkapsling.

Direkt överföring av @State till en underordnad vy utan $ — ytterligare ett typiskt misstag. Om du skickar TextField(text: text) istället för TextField(text: $text) får den underordnade komponenten en vanlig sträng, inte ett Binding. Ändring av text i TextField kommer inte att synkroniseras med det överordnade @State. Använd alltid $-projektionen för att överföra Binding.

Det tredje misstaget — flera @State-egenskaper för relaterad data. Om flera värden logiskt utgör en helhet (t.ex. formulärfält), kombinera dem i en struktur med ett enda @State. Detta förenklar överföring av tillstånd till underordnade vyer och minskar antalet separata uppdateringsutlösare.

Exempel på användning av @State i SwiftUI

@State används i de flesta SwiftUI-projekt för grundläggande interaktivitet. Låt oss titta på ett exempel på ett inloggningsformulär, där @State hanterar textfält och laddningstillstånd. Detta mönster finns i varje applikation — från enkla anteckningar till komplexa företagslösningar.

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("Logga in") {
                login()
            }.disabled(isLoading)
        }
    }

    private func login() {
        isLoading = true
        // Utför nätverksbegäran
    }
}

I exemplet finns fyra @State-egenskaper: email och password för formulärfält, isLoading för laddningsindikering och errorMessage för att visa fel. Varje egenskap hanterar självständigt sin del av gränssnittet. När isLoading ändras blockeras knappen automatiskt via disabled(isLoading) — utan manuell UI-uppdatering.

Vanliga frågor

Varför deklareras @State med private?

@State är avsett för lokalt tillstånd för en specifik vy. Private-modifieraren garanterar att andra komponenter inte kan ändra det direkt, vilket skulle bryta inkapslingen. För extern åtkomst använd $-projektionen.

Kan @State innehålla en array eller ordbok?

Ja, @State stöder arrayer och ordböcker eftersom de är värdetyper. Men när ett arrayelement ändras ritar SwiftUI om hela vyn. För stora listor är det effektivare att använda @StateObject med @Published.

Vad händer när nil tilldelas en @State-egenskap med Optional-typ?

@State fungerar korrekt med Optional-typer. Vid tilldelning av nil upptäcker SwiftUI ändringen och ritar om vyn. Detta är praktiskt för tillstånd som errorMessage: String?, där nil innebär frånvaro av fel.

Hur beter sig @State när vyn visas igen?

@State behåller värdet så länge vyn förblir i hierarkin. Om vyn tas bort från hierarkin och läggs till igen initieras @State på nytt med standardvärdet. För beständighet använd @AppStorage.

Kan @State-ändringar animeras?

Ja, omge ändringen med withAnimation: withAnimation(.easeInOut) { isExpanded.toggle() }. SwiftUI animerar övergången mellan det gamla och nya tillståndet i gränssnittet med den angivna animationstypen.

Sammanfattning

  • @State — Property Wrapper för lokalt tillstånd för en vy, uppdaterar automatiskt gränssnittet
  • Passar för enkla typer: String, Int, Bool, samt strukturer och enum
  • Passar inte för referenstyper (klasser) — använd @StateObject
  • Alltid private — tillstånd bör inte ändras utifrån direkt
  • $-projektion — skapar Binding för att överföra ändringsrätt till underordnade vyer
  • Flera @State i en vy — normal praxis för oberoende tillstånd
  • withAnimation — möjliggör animering av @State-egenskapsändringar

Vi utvecklar en mobil applikation nyckelfärdigt

IT Sectr skapar iOS- och Android-applikationer för startups och företag sedan 2017. Vi ger dig råd och föreslår den bästa lösningen.

Diskutera projektet

Läs också