@State — cos'è, scopo e utilizzo in SwiftUI

Autore: IT Sectr Pubblicato: 2026-06-19 Tempo di lettura: 7 min

@State è un Property Wrapper in SwiftUI per gestire lo stato locale all'interno di una singola vista. SwiftUI ridisegna automaticamente la vista ogni volta che una proprietà @State cambia, rendendo l'interfaccia reattiva senza chiamate di aggiornamento manuali. Secondo la Apple Developer Documentation (2025), @State è consigliato per tipi semplici e strutture appartenenti a una singola vista. @State è il modo più semplice per aggiungere interattività a un'interfaccia SwiftUI.

Punti chiave

  • @State — Property Wrapper per stato locale appartenente a una singola vista
  • Aggiornamento automatico — SwiftUI reinvoca body quando una proprietà @State cambia
  • Tipi semplici — @State funziona con String, Int, Bool, enum e struct
  • Non passare a viste figlie — usa @Binding per modifiche da componenti figli
  • private — le proprietà @State sono sempre dichiarate con il modificatore private

Cos'è @State in SwiftUI?

@State è un Property Wrapper integrato in SwiftUI che consente a una vista di memorizzare e tracciare il proprio stato. Quando un valore @State cambia, SwiftUI ridisegna automaticamente la vista reinvocando la proprietà body. Questa è la base della programmazione reattiva in SwiftUI: lo sviluppatore dichiara lo stato e il framework si occupa della sincronizzazione dell'interfaccia.

@State crea un'area di archiviazione nell'heap gestita da SwiftUI. Quest'area è persistente — sopravvive alle inizializzazioni ripetute della struttura della vista, che avvengono a ogni rendering. SwiftUI utilizza l'identificatore della vista (generato dalla sua posizione nella gerarchia) per legare la proprietà @State a una vista specifica. Grazie a ciò, lo stato non viene resettato quando la vista padre viene aggiornata.

Un limite importante: @State è destinato solo a tipi valore (struct, enum, primitivi). Per i tipi riferimento (classi), usa @StateObject o @ObservedObject. Se assegni una classe a una proprietà @State, SwiftUI non sarà in grado di rilevare le modifiche all'interno dell'oggetto — solo la sostituzione completa del riferimento.

Come funziona @State sotto il cofano?

SwiftUI implementa @State attraverso un meccanismo interno di Storage. Ogni proprietà @State ottiene una cella di memoria dedicata memorizzata in un contenitore di archiviazione speciale della vista. Quando si verifica una scrittura in wrappedValue, SwiftUI notifica il suo grafo delle dipendenze tramite didSet della necessità di ridisegnare.

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

    var body: some View {
        VStack {
            Text("Ciao, \(name)")
            Button(isLoggedIn ? "Esci" : "Accedi") {
                isLoggedIn.toggle()
            }
        }
    }
}

Nell'esempio, ci sono due proprietà @State: name (String) e isLoggedIn (Bool). Quando viene chiamato isLoggedIn.toggle(), SwiftUI segna ContentView come bisognosa di aggiornamento e reinvoca body nel ciclo di rendering successivo. Il punto chiave: le proprietà @State sono sempre dichiarate con il modificatore private — questo segnala che lo stato appartiene esclusivamente alla vista corrente e non dovrebbe essere modificato dall'esterno direttamente.

Per osservare le modifiche, SwiftUI utilizza CurrentValueSubject da Combine. Ogni proprietà @State crea un publisher nascosto che notifica il sistema a ogni cambiamento. Ciò consente a SwiftUI di ridisegnare solo il set minimo necessario di viste, evitando aggiornamenti completi della gerarchia.

Quando usare @State in un progetto

@State è ottimale per stati locali semplici: campi di testo nella ricerca, flag booleani per finestre modali, interruttori di impostazioni, contatori, elementi di lista selezionati. Se un valore viene utilizzato solo in una vista e nei suoi componenti figli (tramite @Binding), @State è la scelta giusta. Per stati che devono sopravvivere alla chiusura della vista (ad esempio, dati del modulo), @State funziona anche finché la vista rimane nella gerarchia.

  • Campi di testo — @State per memorizzare il testo inserito in TextField
  • Flag booleani — @State per mostrare/nascondere finestre modali e sheet
  • Selezione elementi — @State per tracciare la scheda o riga selezionata
  • Contatori — @State per valori numerici con incremento/decremento
  • Calcoli intermedi — @State per memorizzare nella cache i risultati all'interno di una vista

Non usare @State per stati globali dell'applicazione, memorizzazione nella cache di dati di rete o oggetti utilizzati su più schermate. @StateObject e @EnvironmentObject sono progettati per questi scopi. Inoltre, @State non è adatto per memorizzare grandi quantità di dati — ogni modifica ridisegnerà l'intera vista.

@State e @Binding: lavorare insieme

@Binding è un ponte tra @State in una vista padre e una vista figlia che deve modificare quello stato. Il padre dichiara @State, e il componente figlio riceve un Binding tramite la proiezione $. La modifica del Binding nella vista figlia aggiorna automaticamente @State nel padre — e viceversa. Ciò garantisce un flusso di dati unidirezionale con capacità di feedback.

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

Nel listato, ParentView possiede @State text, e ChildView riceve $text come Binding. Il TextField all'interno di ChildView si lega a questo Binding tramite text: $text. Quando l'utente digita nel TextField, il valore cambia in ChildView attraverso il Binding, causando un aggiornamento di @State in ParentView. Entrambe le viste vengono ridisegnate con il nuovo valore.

Errori comuni con @State

L'errore più comune è assegnare una classe a una proprietà @State. Se scrivi @State var model = MyClass(), SwiftUI non sarà in grado di tracciare le modifiche alle proprietà all'interno della classe — solo la sostituzione dell'oggetto. Per le classi, usa sempre @StateObject. Il secondo problema comune è dichiarare @State senza il modificatore private, violando il principio di incapsulamento dello stato.

Passare @State direttamente a una vista figlia senza $ è un altro errore tipico. Se passi TextField(text: text) invece di TextField(text: $text), il componente figlio riceve solo una stringa, non un Binding. Le modifiche al testo nel TextField non verranno sincronizzate con @State del padre. Usa sempre la proiezione $ per passare Binding.

Il terzo errore sono molteplici proprietà @State per dati correlati. Se più valori formano logicamente un tutt'uno (ad esempio, campi del modulo), combinali in un'unica struttura con un singolo @State. Questo semplifica il passaggio dello stato alle viste figlie e riduce il numero di trigger di aggiornamento individuali.

Esempi di utilizzo di @State in SwiftUI

@State viene utilizzato nella maggior parte dei progetti SwiftUI per l'interattività di base. Consideriamo un esempio di modulo di accesso in cui @State gestisce i campi di testo e lo stato di caricamento. Questo pattern appare in ogni applicazione — dalle semplici note alle complesse soluzioni aziendali.

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

    private func login() {
        isLoading = true
        // Esegui richiesta di rete
    }
}

Nell'esempio, ci sono quattro proprietà @State: email e password per i campi del modulo, isLoading per l'indicazione di caricamento e errorMessage per la visualizzazione degli errori. Ogni proprietà gestisce indipendentemente la sua parte dell'interfaccia. Quando isLoading cambia, il pulsante viene automaticamente disabilitato tramite disabled(isLoading) — senza aggiornamento manuale dell'interfaccia.

Domande frequenti

Perché @State viene dichiarato con private?

@State è progettato per lo stato locale di una vista specifica. Il modificatore private garantisce che altri componenti non possano modificarlo direttamente, rompendo l'incapsulamento. Per l'accesso esterno, usa la proiezione $.

@State può contenere un array o un dizionario?

Sì, @State supporta array e dizionari poiché sono tipi valore. Tuttavia, quando un elemento di un array cambia, SwiftUI ridisegna l'intera vista. Per liste grandi, @StateObject con @Published è più efficiente.

Cosa succede quando nil viene assegnato a una proprietà @State con tipo Optional?

@State funziona correttamente con i tipi Optional. Quando nil viene assegnato, SwiftUI rileva la modifica e ridisegna la vista. Questo è comodo per stati come errorMessage: String?, dove nil significa nessun errore.

Come si comporta @State quando la vista riappare?

@State mantiene il valore finché la vista rimane nella gerarchia. Se la vista viene rimossa dalla gerarchia e aggiunta di nuovo, @State viene reinizializzato con il valore predefinito. Per la persistenza, usa @AppStorage.

Si possono animare le modifiche di @State?

Sì, racchiudi la modifica in withAnimation: withAnimation(.easeInOut) { isExpanded.toggle() }. SwiftUI anima la transizione tra il vecchio e il nuovo stato dell'interfaccia con il tipo di animazione specificato.

Riepilogo

  • @State — Property Wrapper per stato locale di una singola vista, aggiorna automaticamente l'interfaccia
  • Funziona con tipi semplici: String, Int, Bool, oltre a struct ed enum
  • Non funziona con tipi riferimento (classi) — usa @StateObject
  • Sempre private — lo stato non dovrebbe essere modificato dall'esterno direttamente
  • Proiezione $ — crea un Binding per passare i diritti di modifica alle viste figlie
  • Più @State in una vista — pratica normale per stati indipendenti
  • withAnimation — permette di animare le modifiche alle proprietà @State

Svilupperemo un'applicazione mobile chiavi in mano

IT Sectr crea applicazioni iOS e Android per startup e aziende dal 2017. Ti consulteremo e ti proporremo la soluzione migliore.

Discuti il progetto

Leggi anche