SwiftUI nello sviluppo mobile: cos'è, concetti chiave e come funziona

Autore: IT Sectr Pubblicato: 2026-07-02 Tempo di lettura: 10 min
SwiftUI è il framework dichiarativo di Apple per creare interfacce su tutte le piattaforme. Secondo Apple SwiftUI Docs (2025), SwiftUI è utilizzato nel 70% delle nuove app sull'App Store. Comprendere i concetti chiave di SwiftUI — View Protocol, @ViewBuilder, NavigationStack — è il fondamento dello sviluppo iOS moderno.

Punti chiave

  • View Protocol — var body: some View. Ogni View è una struttura che segue il protocollo View. body è la descrizione dell'interfaccia.
  • @ViewBuilder — Result Builder per più View nei contenitori. if/else, switch, ForEach all'interno di body.
  • NavigationStack (iOS 16+) — navigazione basata sui dati. path-based, deep linking. Sostituisce NavigationView.
  • @StateObject — proprietà dell'oggetto. @ObservedObject — osservazione. @EnvironmentObject — ambiente.
  • @FocusState — gestione del focus. .task{}, .onAppear{} — ciclo di vita. PreviewProvider — anteprima.

Fondamenti (View Protocol, body, some View, @ViewBuilder)

View Protocol è il protocollo centrale di SwiftUI. Richiede una sola proprietà: var body: some View. body è una proprietà calcolata che restituisce la descrizione dell'interfaccia. SwiftUI chiama body ad ogni cambiamento di stato e renderizza il risultato sulla GPU.

@ViewBuilder

@ViewBuilder è un Result Builder per View. Permette di scrivere più View all'interno di una closure senza return e senza TupleView. Supporta if/else, switch, ForEach. Tutti i contenitori (VStack, HStack, ZStack, Group) usano @ViewBuilder. Un'alternativa è Group { … } per raggruppare senza layout. some View è un Opaque Type. Il compilatore conosce il tipo concreto di View (Text, Button, VStack, ecc.), ma lo restituisce esternamente come some View. Questo permette di cambiare il tipo di body senza modificare la firma. ViewModifier — modificatore di View: .font(), .padding(), .background(). Modificatore personalizzato tramite ViewModifier protocol e .modifier().

swift
// Esempio di View con @ViewBuilder e NavigationStack
struct ContentView: View {
    @State private var items = ["Item 1", "Item 2"]

    var body: some View {
        NavigationStack {
            List(items, id: .self) { item in
                NavigationLink(item) {
                    DetailView(item: item)
                }
            }
            .navigationTitle("Items")
            .toolbar {
                ToolbarItem(placement: .navigationBarTrailing) {
                    Button("Add") {
                        items.append("New Item")
                    }
                }
            }
        }
    }
}

// DetailView con @StateObject
struct DetailView: View {
    let item: String
    @StateObject private var viewModel = DetailViewModel()

    var body: some View {
        Text(item)
            .task {
                await viewModel.loadDetails(for: item)
            }
    }
}

Modificatori e contenitori (ViewModifier, NavigationStack, List, Form)

NavigationStack (iOS 16+) — navigazione basata sui dati. Prende un percorso (array di valori hashable) e mostra la destinazione tramite navigationDestination. Sostituisce NavigationLink con viste di destinazione. NavigationLink — pulsante per navigare nello stack. List — elenco verticale con sezioni, swipe, eliminazione e trascinamento. Form — una List specializzata per impostazioni: sezioni, selettori, interruttori, campi di testo. Section — raggruppamento in List/Form con intestazione e piè di pagina. ViewModifier — modificatori personalizzati per riutilizzare stili. .modifier(CustomModifier()) — applicazione.

List e Form in dettaglio

List in SwiftUI è l'equivalente di UITableView. Supporta .onDelete, .onMove, .refreshable. SwipeActions — .swipeActions { Button("Elimina", role: .destructive) { } }. Form — ottimizzato per impostazioni: DatePicker, Toggle, Stepper, Picker. Section con header/footer — per raggruppare. OutlineGroup — elenchi gerarchici (equivalente di UITableView con sezioni). DisclosureGroup — sezione richiudibile con contenuto. IT Sectr raccomanda List per i dati e Form per le impostazioni.

PreviewProvider — protocollo per anteprime in Xcode Canvas. Canvas — anteprima interattiva di SwiftUI (richiede @main e Swift 5.9+). @ScaledMetric — dimensione adattiva che scala con Dynamic Type.

Gestione dello stato (@StateObject, @ObservedObject, @EnvironmentObject, @FocusState)

Property Wrappers sono la base della gestione dello stato in SwiftUI. @State — stato locale (value type). @Binding — connessione allo stato genitore. @StateObject — crea un ObservableObject. SwiftUI gestisce il ciclo di vita dell'oggetto. @ObservedObject — osserva un ObservableObject esterno. @EnvironmentObject — oggetto dall'ambiente (dependency injection tramite .environmentObject()). @Environment — valori di sistema (.colorScheme, .locale). @AppStorage — UserDefaults. @FetchRequest — query Core Data. @FocusState — focus di input.

Wrapper Scopo Proprietà
@StateStato locale (value type)La View possiede
@BindingConnessione allo stato genitoreIl genitore possiede
@StateObjectCrea ObservableObjectLa View possiede
@ObservedObjectOsserva oggetto esternoProprietario esterno
@EnvironmentObjectOggetto dall'ambienteL'antenato possiede
@EnvironmentValore di sistemaIl sistema
@AppStorageUserDefaultsUserDefaults
@FocusStateFocus di inputLa View possiede

@StateObject vs @ObservedObject: @StateObject crea un oggetto, @ObservedObject lo osserva. Usa @StateObject per la creazione iniziale del modello nella gerarchia, @ObservedObject per passare alle viste figlie. @FocusState — gestione del focus: .focused($field, equals: .email). Supporta enum per più campi.

Valori di ambiente e DI

@Environment — valori di sistema: colorScheme, locale, sizeCategory, layoutDirection, managedObjectContext. Valori di ambiente personalizzati — valore personalizzato tramite EnvironmentKey. Utilizzato per dependency injection: passare servizi senza parametri espliciti. Modificatore .environment() — imposta un valore nella gerarchia. @EnvironmentObject — ObservableObject da .environmentObject(). Differisce da @Environment in quanto passa un tipo per riferimento. IT Sectr raccomanda @Environment per i valori di sistema e @EnvironmentObject per i servizi.

Ciclo di vita (.task, .onAppear, .onDisappear)

.task{} — operazione asincrona all'apparizione della vista. Cancellazione automatica alla scomparsa. Sostituisce .onAppear per async/await. .onAppear{} — operazione sincrona all'apparizione. .onDisappear{} — operazione alla scomparsa. .onChange(of:) — reazione ai cambiamenti di valore. .onReceive(Publisher) — reazione al publisher Combine. Ciclo di vita della View in SwiftUI: init → onAppear → body (rendering) → onDisappear. Al cambiamento di stato: body → diff → re-rendering. IT Sectr raccomanda .task per il caricamento asincrono e .onAppear per le analisi.

Animazione in SwiftUI

.animation() — modificatore di animazione. .transition() — animazione di apparizione/scomparsa. withAnimation — animazione esplicita dei cambiamenti di stato. matchedGeometryEffect — animazione tra viste diverse (hero animation). PhaseAnimator (iOS 17+) — animazione multifase basata su enum. KeyframeAnimator (iOS 17+) — animazione fotogramma per fotogramma con keyframes. Le animazioni SwiftUI vengono eseguite sulla GPU tramite Core Animation. IT Sectr raccomanda .spring() per animazioni naturali e .interpolatingSpring per effetti fisici.

Flusso di dati (Bindings, @Published, ObservableObject)

ObservableObject — protocollo per oggetti con proprietà @Published. SwiftUI si abbona al publisher objectWillChange. @Published — pubblica i cambiamenti di proprietà. @StateObject — crea ObservableObject, gestisce il ciclo di vita. @ObservedObject — osserva esterno. Combine — framework per la programmazione reattiva. @EnvironmentObject — DI tramite ambiente. .environmentObject() imposta, @EnvironmentObject legge. MVVM — architettura standard: View (SwiftUI) — ViewModel (ObservableObject) — Model. IT Sectr raccomanda MVVM + @StateObject per i ViewModel principali.

swift
class UserViewModel: ObservableObject {
    @Published var users: [User] = []
    @Published var isLoading = false

    func loadUsers() async {
        isLoading = true
        defer { isLoading = false }
        do {
            users = try await api.fetchUsers()
        } catch {
            print("Errore: \(error)")
        }
    }
}

struct UsersView: View {
    @StateObject private var viewModel = UserViewModel()

    var body: some View {
        List(viewModel.users, id: \.id) { user in
            Text(user.name)
        }
        .task { await viewModel.loadUsers() }
        .overlay {
            if viewModel.isLoading { ProgressView() }
        }
    }
}

Accessibilità e localizzazione

Accessibilità in SwiftUI: .accessibilityLabel(), .accessibilityHint(), .accessibilityValue(), .accessibilityAddTraits(). VoiceOver legge le etichette di accessibilità. Dynamic Type — @ScaledMetric, @DynamicProperty. Localizzazione: String(localized:) (SwiftUI + String Catalog). LocalizedStringKey — traduzione automatica. Regole plurali — tramite String Catalog (one, few, many, other). Da destra a sinistra (arabo, ebraico) — supportato automaticamente. .environment(.layoutDirection, .rightToLeft). IT Sectr raccomanda etichette di accessibilità per tutti gli elementi interattivi.

swift
struct AccessibleButton: View {
    let action: () -> Void

    var body: some View {
        Button(action: action) {
            Label("Settings", systemImage: "gear")
        }
        .accessibilityLabel("Open Settings")
        .accessibilityHint("Double tap to navigate to settings screen")
        .accessibilityAddTraits(.isButton)
    }
}

// Supporto Dynamic Type
struct ScalableText: View {
    @ScaledMetric private var fontSize: CGFloat = 17

    var body: some View {
        Text("Hello, World!")
            .font(.system(size: fontSize))
    }
}

Grafici e visualizzazione (Swift Charts)

Swift Charts (iOS 16+) — framework per creare grafici. Chart { } — contenitore base. BarMark, LineMark, PointMark, AreaMark, RuleMark — marcatori. ForEach per i dati. ChartAxis — personalizzazione degli assi. .chartXAxis, .chartYAxis. ChartLegend — legenda. Interpolazione — catmullRom, linear, step. Animazione — .animation() per Chart. IT Sectr raccomanda Swift Charts per grafici integrati e Charts (DGCharts) per quelli complessi.

swift
import Charts

struct MonthlySales: Identifiable {
    let id = UUID()
    let month: String
    let sales: Double
}

struct SalesChart: View {
    let data: [MonthlySales]

    var body: some View {
        Chart(data) { item in
            BarMark(
                x: .value("Month", item.month),
                y: .value("Sales", item.sales)
            )
            .foregroundStyle(.blue.gradient)
        }
        .chartXAxisLabel("Month")
        .chartYAxisLabel("Sales")
        .frame(height: 200)
        .padding()
    }
}

Swift Package Manager (SPM) — il gestore di dipendenze di Apple. Integrato in Xcode. Supporta: pacchetti binari, risorse, test, swift-6 concorrenza rigorosa. Pubblicazione di pacchetti tramite GitHub con tag semver. SPM è lo standard de facto per le dipendenze Swift, sostituendo CocoaPods e Carthage. IT Sectr raccomanda SPM per tutti i nuovi progetti.

Swift Concurrency (async/await, TaskGroup, AsyncSequence) — async/await integrato in Swift 5.5+. Task — unità di asincronia. TaskGroup — attività parallele. AsyncSequence — sequenza asincrona (AsyncStream, AsyncAlgorithms). Task Local Values — dati contestuali per Task. Swift Concurrency sostituisce completamente Combine per le operazioni asincrone.

Domande frequenti

Cos'è View Protocol in SwiftUI?

View Protocol è il protocollo base. Richiede var body: some View. body è la descrizione dell'interfaccia renderizzata sulla GPU.

Cos'è @ViewBuilder e a cosa serve?

@ViewBuilder è un Result Builder per più View. Permette if/else, switch, ForEach all'interno dei contenitori.

Qual è la differenza tra @StateObject e @ObservedObject?

@StateObject crea un oggetto. @ObservedObject ne osserva uno esistente. @StateObject per la prima creazione nella gerarchia.

Cos'è NavigationStack in iOS 16+?

NavigationStack — navigazione basata sui dati. path-based, deep linking. Sostituisce NavigationView.

Come funziona @FocusState in SwiftUI?

@FocusState — gestione del focus di input. Modificatore .focused(). Supporta enum per più campi.

Riepilogo

  • View Protocol — var body: some View. Base di SwiftUI. Ogni View è una struct.
  • @ViewBuilder — sintassi dichiarativa per più View. if/else, ForEach in body.
  • NavigationStack (iOS 16+) — navigazione moderna. data-driven, path-based.
  • @StateObject — proprietà del modello. @ObservedObject — osservazione. @EnvironmentObject — DI.
  • @FocusState — gestione del focus. Utile per moduli e campi di input multipli.
  • .task{} — operazione asincrona con cancellazione automatica. .onAppear{} — sincrona.
  • PreviewProvider e Canvas — anteprime in Xcode. @ScaledMetric — dimensioni adattive.

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