0Pricing
Swift Academy · Lekcja

Powiązanie view modeli z widokami

Łączenie view modeli z SwiftUI i Combine.

Powiązanie view modeli z widokami to bezpłatna lekcja Swift Academy na CoddyKit. To lekcja 2 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Swift Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Swift Academy zawiera 4 lekcji w sumie.

Łączenie ViewModelu z Widokiem

ViewModel jest użyteczny tylko wtedy, gdy Widok reaguje na jego zmiany. W SwiftUI za tę reaktywność odpowiadają oparte na Combine property wrappers: @Published, @StateObject i @ObservedObject.

Razem tworzą automatyczne wiązanie: gdy ViewModel się zmienia, Widok jest renderowany ponownie.

ObservableObject

Aby SwiftUI mogło go obserwować, ViewModel musi być zgodny z protokołem ObservableObject. Protokół ten udostępnia publisher objectWillChange, który emituje powiadomienie przed każdą zmianą.

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

    func increment() {
        count += 1
    }
}

Właściwości @Published

Oznaczenie właściwości za pomocą @Published automatycznie emituje powiadomienie o zmianie za każdym razem, gdy zostanie ustawiona jej wartość.

Każda właściwość @Published zasila publisher objectWillChange obiektu, dzięki czemu Widok dokładnie wie, kiedy należy go odświeżyć.

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

@StateObject

@StateObject informuje Widok, że ma utworzyć ViewModel i zarządzać jego cyklem życia. SwiftUI tworzy go raz i zachowuje między kolejnymi renderowaniami tego Widoku.

@StateObject należy używać w miejscu, w którym ViewModel jest tworzony po raz pierwszy.

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

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

@ObservedObject

@ObservedObject służy do obsługi ViewModelu utworzonego w innym miejscu i przekazanego do Widoku. Widok go obserwuje, ale nie zarządza jego cyklem życia.

Należy używać go w widokach podrzędnych, które otrzymują ViewModel od widoku nadrzędnego.

struct BadgeView: View {
    @ObservedObject var viewModel: CounterViewModel

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

StateObject a ObservedObject

Kluczowa różnica dotyczy własności:

  • @StateObject — Widok jest jego właścicielem; obiekt przetrwa ponowne renderowanie
  • @ObservedObject — obiekt jest przekazywany; Widok nie jest jego właścicielem

Użycie @ObservedObject w miejscu, w którym należy użyć @StateObject, może spowodować ponowne tworzenie obiektu i utratę jego stanu przy każdej aktualizacji widoku nadrzędnego.

Przekazywanie ViewModelu do widoków podrzędnych

Należy utworzyć ViewModel raz za pomocą @StateObject w widoku nadrzędnym, a następnie przekazać go widokom podrzędnym, które oznaczą go za pomocą @ObservedObject.

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

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

Wiązania dwukierunkowe

W przypadku pól tekstowych potrzebne jest dwukierunkowe Binding. SwiftUI tworzy je na podstawie właściwości @Published za pomocą prefiksu $ przy wrapperze.

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

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

Sterowanie stanem interfejsu

Widok powinien wyprowadzać wszystko, co wyświetla, z opublikowanych właściwości. Wskaźniki ładowania, banery błędów i zawartość — wszystko wynika ze stanu ViewModelu.

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

Reagowanie na stan

Widok przełącza się na podstawie stanu ViewModelu, aby renderować właściwy interfejs użytkownika. Nie ma tu imperatywnego kodu pokazującego i ukrywającego elementy, lecz jedynie deklaratywne odwzorowanie.

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

Utrzymywanie aktualizacji w głównym wątku

SwiftUI wymaga, aby zmiany opublikowanych właściwości zachodziły w głównym wątku. Gdy ViewModel aktualizuje stan po zakończeniu pracy asynchronicznej, należy oznaczyć go za pomocą @MainActor, aby to zagwarantować.

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

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

Szybkie sprawdzenie

Sprawdź swoją wiedzę o wiązaniach.

Podsumowanie

Połączono ViewModel z Widokiem za pomocą wiązań SwiftUI:

  • ObservableObject + @Published emitują powiadomienia o zmianach
  • @StateObject tworzy ViewModel i zarządza jego cyklem życia
  • @ObservedObject obserwuje przekazany ViewModel
  • @MainActor utrzymuje aktualizacje asynchroniczne w głównym wątku

Dzięki reaktywnym wiązaniom Widok zawsze automatycznie odzwierciedla najnowszy stan ViewModelu.

Często zadawane pytania

Czy lekcja „Powiązanie view modeli z widokami” jest bezpłatna?

Tak — pełny tekst „Powiązanie view modeli z widokami” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Swift Academy, przejdź na CoddyKit PRO. Kurs Swift Academy zawiera 4 lekcji w sumie.

Co nauczysz się w „Powiązanie view modeli z widokami”?

Łączenie view modeli z SwiftUI i Combine. Ćwiczysz Swift Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.

Czy potrzebuję doświadczenia, aby zacząć Swift Academy?

Nie wymagamy żadnego doświadczenia. Swift Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 2 z 4.

Ile czasu zajmuje lekcja „Powiązanie view modeli z widokami”?

Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.

Czy mogę pisać i uruchamiać kod w tej lekcji Swift Academy?

Tak. Każda lekcja Swift Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.

Wszystkie lekcje w tym kursie

  1. Wzorzec MVVM
  2. Powiązanie view modeli z widokami
  3. Wzorzec Coordinator
  4. Testowanie view modeli
← Powrót do Swift Academy