Vai al contenuto

Gestione dello stato

In SwiftUI esistono diversi strumenti per gestire i dati. La scelta dipende da dove vive il dato e da chi lo possiede. Con il sistema più recente, Apple usa il framework Observation per rendere i modelli osservabili in modo più semplice.

@State In SwiftUI l’interfaccia è costruita componendo viste piccole e riutilizzabili. Questo favorisce il riutilizzo del codice e rende più semplice mantenere il progetto nel tempo.

Gestione dello stato @State si usa per dati semplici e locali, posseduti dalla view stessa. È adatto, per esempio, a contatori, campi di testo, toggle o piccole informazioni temporanee.

import SwiftUI
struct CounterView: View {
    @State private var counter = 0
    var body: some View {
        VStack {
            Text("Counter: \(counter)")
            Button("Incrementa") {
                counter += 1
            }
        }
    }
}

struct CounterView_Previews: PreviewProvider {
    static var previews: some View {
        CounterView()
    }
}

Quando counter cambia, SwiftUI aggiorna automaticamente la view.

@Observable Se vuoi creare un modello dati osservabile, nelle versioni recenti puoi usare la macro @Observable del framework Observation. Questa macro rende il tipo osservabile senza dover usare ObservableObject e @Published per ogni proprietà.

import SwiftUI 
import Observation 

@Observable 
class UserSettings { 
    var username = "" 
    var isLoggedIn = false 
} 

Con @Observable, SwiftUI osserva direttamente le proprietà effettivamente lette dalla view, aggiornando solo ciò che dipende da quei dati. Questo sistema è più semplice e più preciso rispetto al vecchio approccio basato su ObservableObject.

**Uso di un modello @Observable in una view ** Se una view possiede il modello, puoi conservarlo con @State. Questo è uno dei cambiamenti più importanti del nuovo sistema.

import SwiftUI 
import Observation 

@Observable 
class UserSettings { 
    var username = "" 
    var isLoggedIn = false 
} 

struct LoginView: View { 
    @State private var settings = UserSettings() 
    var body: some View { 
        VStack { 
            TextField("Username", text: $settings.username) 
                .textFieldStyle(.roundedBorder) 
            Button("Login") { 
                settings.isLoggedIn = true 
            } 
            if settings.isLoggedIn { 
                Text("Welcome, \(settings.username)!") 
            } 
        } .padding() 
    } 
} 

Qui: settings è il modello osservabile; settings.username e settings.isLoggedIn sono proprietà osservate dalla view; quando cambiano, la UI si aggiorna.

@Bindable Quando una view deve creare un binding verso una proprietà di un modello @Observable, puoi usare @Bindable. Serve soprattutto quando passi un modello a una subview e vuoi collegare controlli come TextField, Toggle o Stepper direttamente alle sue proprietà.

import SwiftUI 
import Observation 

@Observable 
class Profile { 
    var name = "" 
    var notificationsEnabled = true 
} 

struct ProfileForm: View { 
    @Bindable var profile: Profile 
    var body: some View { 
        Form { 
            TextField("Nome", text: $profile.name) 
            Toggle("Notifiche", isOn: $profile.notificationsEnabled) 
        } 
    } 
} 

@Bindable non crea il modello: permette di creare binding verso un modello osservabile già esistente.

@Environment Per dati condivisi in molte parti dell’app, puoi usare l’environment. Con il sistema Observation, SwiftUI supporta l’uso di modelli osservabili anche in questo contesto. Un modello condiviso può essere inserito nell’ambiente e poi letto nelle view che ne hanno bisogno, evitando di passarlo manualmente lungo tutta la gerarchia.

Nota

Nei progetti moderni con target iOS 17 o superiore è consigliabile conoscere @Observable e @Bindable. Nei progetti più vecchi o compatibili con versioni precedenti si incontrano spesso ObservableObject, @Published, @ObservedObject e @StateObject.