Swift Academy · Lektion

Binda view models till vyer

Anslut view models med SwiftUI och Combine.

Lektion 2 av 413 steg

Binda view models till vyer är en gratis lektion i Swift Academy på CoddyKit. Detta är lektion 2 av 4. Du kan läsa vilka 3 lektioner som helst i den här lärvägen kostnadsfritt i sin helhet – därefter låser CoddyKit PRO upp alla lektioner, plus praktisk övning med en inbyggd kodredigerare och en AI-lärare dygnet runt. Den ingår i lärvägen för Swift Academy, och Era framsteg synkroniseras mellan webben och CoddyKit-appen. Kursen i Swift Academy innehåller totalt 4 lektioner.

Koppla ViewModel till View

En ViewModel är bara användbar när View reagerar på dess ändringar. I SwiftUI drivs denna reaktivitet av de Combine-baserade property wrappers @Published, @StateObject och @ObservedObject.

Tillsammans bildar de en automatisk bindning: när ViewModel ändras renderas View på nytt.

ObservableObject

För att kunna observeras av SwiftUI måste en ViewModel följa protokollet ObservableObject. Protokollet ger den en objectWillChange-publisher som skickar en signal före varje ändring.

final class CounterViewModel: ObservableObject {
    @Published var count: Int = 0

    func increment() {
        count += 1
    }
}

Egenskaper med @Published

När en egenskap markeras med @Published skickas automatiskt en ändringsnotis varje gång dess värde tilldelas.

Varje @Published-egenskap matas in i objektets objectWillChange-publisher, så View vet exakt när den ska uppdateras.

final class SearchViewModel: ObservableObject {
    @Published var query: String = ""
    @Published var results: [String] = []
}

@StateObject

@StateObject talar om för en View att skapa och äga en ViewModel. SwiftUI instansierar den en gång och håller den vid liv när View renderas om.

Använd @StateObject där ViewModel skapas första gången.

struct CounterView: View {
    @StateObject private var viewModel = CounterViewModel()

    var body: some View {
        Button("Count: \(viewModel.count)") {
            viewModel.increment()
        }
    }
}

@ObservedObject

@ObservedObject används för en ViewModel som har skapats någon annanstans och skickats in. View observerar den men äger inte dess livscykel.

Använd den i underordnade vyer som tar emot en ViewModel från en överordnad vy.

struct BadgeView: View {
    @ObservedObject var viewModel: CounterViewModel

    var body: some View {
        Text("Total: \(viewModel.count)")
    }
}

StateObject jämfört med ObservedObject

Den avgörande skillnaden är ägarskapet:

  • @StateObject — View äger objektet; det överlever omrenderingar
  • @ObservedObject — objektet skickas in; View äger det inte

Om ni använder @ObservedObject där ni borde använda @StateObject kan objektet skapas om och förlora sitt tillstånd vid varje uppdatering av den överordnade vyn.

Skicka vidare en ViewModel

Skapa ViewModel en gång med @StateObject i den överordnade vyn och skicka den sedan till underordnade vyer som markerar den med @ObservedObject.

struct ParentView: View {
    @StateObject private var viewModel = CounterViewModel()

    var body: some View {
        VStack {
            BadgeView(viewModel: viewModel)
            Button("Add") { viewModel.increment() }
        }
    }
}

Tvåvägsbindningar

För inmatningsfält som textfält behöver ni en tvåvägsbindning med Binding. SwiftUI skapar en sådan från en @Published-egenskap genom att använda prefixet $ på omslaget.

struct SearchView: View {
    @StateObject private var viewModel = SearchViewModel()

    var body: some View {
        TextField("Search", text: $viewModel.query)
    }
}

Styra UI-tillstånd

View bör härleda allt den visar från publicerade egenskaper. Laddningsindikatorer, felmeddelanden och innehåll ska alla flöda från ViewModel-tillståndet.

final class FeedViewModel: ObservableObject {
    enum State { case loading, loaded([String]), error(String) }
    @Published var state: State = .loading
}

Reagera på tillstånd

View växlar utifrån ViewModel-tillståndet för att rendera rätt UI. Det finns ingen imperativ kod för att visa eller dölja något, utan bara en deklarativ mappning.

struct FeedView: View {
    @StateObject var viewModel = FeedViewModel()
    var body: some View {
        switch viewModel.state {
        case .loading: ProgressView()
        case .loaded(let items): List(items, id: \.self) { Text($0) }
        case .error(let message): Text(message)
        }
    }
}

Hålla uppdateringar på huvudtråden

SwiftUI kräver att publicerade ändringar görs på huvudtråden. När en ViewModel uppdaterar tillstånd efter asynkront arbete ska ni annotera den med @MainActor för att garantera detta.

@MainActor
final class ProfileViewModel: ObservableObject {
    @Published var name: String = ""

    func load() async {
        name = await fetchName()
    }
}

Snabb kontroll

Testa era kunskaper om bindningar.

Sammanfattning

Ni har kopplat ViewModels till Views med SwiftUI-bindningar:

  • ObservableObject + @Published skickar ändringsnotiser
  • @StateObject skapar och äger en ViewModel
  • @ObservedObject observerar en ViewModel som har skickats in
  • @MainActor håller asynkrona uppdateringar på huvudtråden

Med reaktiva bindningar på plats återspeglar View alltid automatiskt det senaste tillståndet i ViewModel.

Gratis att börja

Lär dig Swift med en AI-lärare – gratis

Skriv och kör riktig kod i webbläsaren, få omedelbar hjälp av en AI-lärare dygnet runt och fortsätt där du slutade – på webben eller i appen.

Kurser
122
Lektioner
409

Vanliga frågor

Är lektionen ”Binda view models till vyer” gratis?

Ja – du kan läsa vilka 3 lektioner som helst i lärvägen Swift Academy, inklusive ”Binda view models till vyer”, kostnadsfritt i sin helhet här på webben. Därefter låser CoddyKit PRO upp alla lektioner, plus interaktiv övning med en inbyggd kodredigerare och en AI-lärare dygnet runt. Kursen i Swift Academy innehåller totalt 4 lektioner.

Vad lär jag mig i ”Binda view models till vyer”?

Anslut view models med SwiftUI och Combine. Ni övar på Swift Academy med praktisk kod som körs direkt i webbläsaren, medan en AI-handledare som är tillgänglig dygnet runt svarar på Era frågor under lektionen.

Behöver jag någon erfarenhet för att börja lära mig Swift Academy?

Du behöver inga förkunskaper. Utbildningen i Swift Academy på CoddyKit är upplagd för allt från nybörjare till avancerade elever, så att du kan börja här eller från början och gå fram i din egen takt. Detta är lektion 2 av 4.

Hur lång tid tar lektionen ”Binda view models till vyer”?

De flesta CoddyKit-lektioner tar cirka 5–10 minuter. Varje lektion är kort och interaktiv, så att du gör stadiga framsteg och kan fortsätta precis där du slutade – på webben eller i appen.

Kan jag skriva och köra kod i den här Swift Academy-lektionen?

Ja. Varje Swift Academy-lektion innehåller en inbyggd kodredigerare, så att du kan skriva och köra riktig kod direkt i webbläsaren och få omedelbar AI-feedback – utan lokal installation.

Alla lektioner i den här kursen

  1. MVVM-mönstret
  2. Binda view models till vyer
  3. Coordinator-mönstret
  4. Testa view models
← Tillbaka till Swift Academy