SwiftUI w programowaniu mobilnym: co to jest, kluczowe pojęcia i jak działa

Autor: IT Sectr Opublikowano: 2026-07-02 Czas czytania: 10 min
SwiftUI to deklaratywny framework Apple do budowania interfejsów na wszystkich platformach. Według Apple SwiftUI Docs (2025), SwiftUI jest używany w 70% nowych aplikacji w App Store. Zrozumienie kluczowych pojęć SwiftUI — View Protocol, @ViewBuilder, NavigationStack — to podstawa nowoczesnego programowania iOS.

Najważniejsze punkty

  • View Protocol — var body: some View. Każdy View to struktura zgodna z protokołem View. body to opis interfejsu.
  • @ViewBuilder — Result Builder dla wielu Views w kontenerach. if/else, switch, ForEach wewnątrz body.
  • NavigationStack (iOS 16+) — nawigacja oparta na danych. path-based, deep linking. Zastępuje NavigationView.
  • @StateObject — własność obiektu. @ObservedObject — obserwacja. @EnvironmentObject — środowisko.
  • @FocusState — zarządzanie fokusem. .task{}, .onAppear{} — cykl życia. PreviewProvider — podgląd.

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

View Protocol to centralny protokół SwiftUI. Wymaga tylko jednej właściwości: var body: some View. body to właściwość obliczana zwracająca opis interfejsu. SwiftUI wywołuje body przy każdej zmianie stanu i renderuje wynik na GPU.

@ViewBuilder

@ViewBuilder to Result Builder dla View. Pozwala pisać wiele Views wewnątrz closure bez return i bez TupleView. Obsługuje if/else, switch, ForEach. Wszystkie kontenery (VStack, HStack, ZStack, Group) używają @ViewBuilder. Alternatywą jest Group { … } do grupowania bez układu. some View to Opaque Type. Kompilator zna konkretny typ View (Text, Button, VStack itp.), ale zwraca go zewnętrznie jako some View. Pozwala to zmienić typ body bez zmiany sygnatury. ViewModifier — modyfikator View: .font(), .padding(), .background(). Niestandardowy modyfikator przez ViewModifier protocol i .modifier().

swift
// Przykład View z @ViewBuilder i 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 z @StateObject
struct DetailView: View {
    let item: String
    @StateObject private var viewModel = DetailViewModel()

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

Modyfikatory i kontenery (ViewModifier, NavigationStack, List, Form)

NavigationStack (iOS 16+) — nawigacja oparta na danych. Przyjmuje ścieżkę (tablicę wartości hashable) i wyświetla miejsce docelowe przez navigationDestination. Zastępuje NavigationLink z widokami docelowymi. NavigationLink — przycisk do nawigacji w stosie. List — pionowa lista z sekcjami, przesunięciami, usuwaniem i przeciąganiem. Form — wyspecjalizowana List dla ustawień: sekcje, selektory, przełączniki, pola tekstowe. Section — grupowanie w List/Form z nagłówkiem i stopką. ViewModifier — niestandardowe modyfikatory do ponownego używania stylów. .modifier(CustomModifier()) — zastosowanie.

List i Form szczegółowo

List w SwiftUI to odpowiednik UITableView. Obsługuje .onDelete, .onMove, .refreshable. SwipeActions — .swipeActions { Button("Usuń", role: .destructive) { } }. Form — zoptymalizowany dla ustawień: DatePicker, Toggle, Stepper, Picker. Section z header/footer — do grupowania. OutlineGroup — listy hierarchiczne (odpowiednik UITableView z sekcjami). DisclosureGroup — zwijana sekcja z zawartością. IT Sectr zaleca List dla danych i Form dla ustawień.

PreviewProvider — protokół dla podglądów w Xcode Canvas. Canvas — interaktywny podgląd SwiftUI (wymaga @main i Swift 5.9+). @ScaledMetric — adaptacyjny rozmiar skalujący się z Dynamic Type.

Zarządzanie stanem (@StateObject, @ObservedObject, @EnvironmentObject, @FocusState)

Property Wrappers to podstawa zarządzania stanem w SwiftUI. @State — stan lokalny (typ wartości). @Binding — połączenie ze stanem rodzica. @StateObject — tworzy ObservableObject. SwiftUI zarządza cyklem życia obiektu. @ObservedObject — obserwuje zewnętrzny ObservableObject. @EnvironmentObject — obiekt ze środowiska (wstrzykiwanie zależności przez .environmentObject()). @Environment — wartości systemowe (.colorScheme, .locale). @AppStorage — UserDefaults. @FetchRequest — zapytanie Core Data. @FocusState — fokus wprowadzania.

Wrapper Przeznaczenie Własność
@StateStan lokalny (typ wartości)View posiada
@BindingPołączenie ze stanem rodzicaRodzic posiada
@StateObjectTworzenie ObservableObjectView posiada
@ObservedObjectObserwacja zewnętrznego obiektuZewnętrzny właściciel
@EnvironmentObjectObiekt ze środowiskaPrzodek posiada
@EnvironmentWartość systemowaSystem
@AppStorageUserDefaultsUserDefaults
@FocusStateFokus wprowadzaniaView posiada

@StateObject vs @ObservedObject: @StateObject tworzy obiekt, @ObservedObject go obserwuje. Użyj @StateObject do pierwszego tworzenia modelu w hierarchii, @ObservedObject do przekazywania widokom potomnym. @FocusState — zarządzanie fokusem: .focused($field, equals: .email). Obsługuje enum dla wielu pól.

Wartości środowiskowe i DI

@Environment — wartości systemowe: colorScheme, locale, sizeCategory, layoutDirection, managedObjectContext. Niestandardowe wartości środowiskowe — niestandardowa wartość przez EnvironmentKey. Używane do wstrzykiwania zależności: przekazywanie usług bez jawnych parametrów. Modyfikator .environment() — ustawia wartość w hierarchii. @EnvironmentObject — ObservableObject z .environmentObject(). Różni się od @Environment tym, że przekazuje typ referencyjny. IT Sectr zaleca @Environment dla wartości systemowych i @EnvironmentObject dla usług.

Cykl życia (.task, .onAppear, .onDisappear)

.task{} — operacja asynchroniczna przy pojawieniu się widoku. Automatyczne anulowanie przy zniknięciu. Zastępuje .onAppear dla async/await. .onAppear{} — operacja synchroniczna przy pojawieniu. .onDisappear{} — operacja przy zniknięciu. .onChange(of:) — reakcja na zmiany wartości. .onReceive(Publisher) — reakcja na publisher Combine. Cykl życia View w SwiftUI: init → onAppear → body (renderowanie) → onDisappear. Przy zmianie stanu: body → diff → ponowne renderowanie. IT Sectr zaleca .task dla ładowania asynchronicznego i .onAppear dla analityki.

Animacja w SwiftUI

.animation() — modyfikator animacji. .transition() — animacja pojawiania/znikania. withAnimation — jawna animacja zmian stanu. matchedGeometryEffect — animacja między różnymi widokami (hero animation). PhaseAnimator (iOS 17+) — wielofazowa animacja oparta na enum. KeyframeAnimator (iOS 17+) — animacja klatka po klatce z klatkami kluczowymi. Animacje SwiftUI są wykonywane na GPU przez Core Animation. IT Sectr zaleca .spring() dla naturalnych animacji i .interpolatingSpring dla efektów fizycznych.

Przepływ danych (Bindings, @Published, ObservableObject)

ObservableObject — protokół dla obiektów z właściwościami @Published. SwiftUI subskrybuje publisher objectWillChange. @Published — publikuje zmiany właściwości. @StateObject — tworzy ObservableObject, zarządza cyklem życia. @ObservedObject — obserwuje zewnętrzny. Combine — framework do programowania reaktywnego. @EnvironmentObject — DI przez środowisko. .environmentObject() ustawia, @EnvironmentObject czyta. MVVM — standardowa architektura: View (SwiftUI) — ViewModel (ObservableObject) — Model. IT Sectr zaleca MVVM + @StateObject dla głównych ViewModel.

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("Błąd: \(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() }
        }
    }
}

Dostępność i lokalizacja

Dostępność w SwiftUI: .accessibilityLabel(), .accessibilityHint(), .accessibilityValue(), .accessibilityAddTraits(). VoiceOver czyta etykiety dostępności. Dynamic Type — @ScaledMetric, @DynamicProperty. Lokalizacja: String(localized:) (SwiftUI + String Catalog). LocalizedStringKey — automatyczne tłumaczenie. Reguły liczby mnogiej — przez String Catalog (one, few, many, other). Od prawej do lewej (arabski, hebrajski) — obsługiwane automatycznie. .environment(.layoutDirection, .rightToLeft). IT Sectr zaleca etykiety dostępności dla wszystkich elementów interaktywnych.

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

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

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

Wykresy i wizualizacja (Swift Charts)

Swift Charts (iOS 16+) — framework do tworzenia wykresów. Chart { } — podstawowy kontener. BarMark, LineMark, PointMark, AreaMark, RuleMark — znaczniki. ForEach dla danych. ChartAxis — dostosowywanie osi. .chartXAxis, .chartYAxis. ChartLegend — legenda. Interpolacja — catmullRom, linear, step. Animacja — .animation() dla Chart. IT Sectr zaleca Swift Charts dla wbudowanych wykresów i Charts (DGCharts) dla złożonych.

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) — menedżer zależności Apple. Zintegrowany z Xcode. Obsługuje: pakiety binarne, zasoby, testy, ścisłą współbieżność swift-6. Publikowanie pakietów przez GitHub z tagiem semver. SPM to de facto standard dla zależności Swift, wypierający CocoaPods i Carthage. IT Sectr zaleca SPM dla wszystkich nowych projektów.

Swift Concurrency (async/await, TaskGroup, AsyncSequence) — async/await wbudowane w Swift 5.5+. Task — jednostka asynchroniczności. TaskGroup — równoległe zadania. AsyncSequence — sekwencja asynchroniczna (AsyncStream, AsyncAlgorithms). Task Local Values — dane kontekstowe dla Task. Swift Concurrency całkowicie zastępuje Combine dla operacji asynchronicznych.

Często zadawane pytania

Czym jest View Protocol w SwiftUI?

View Protocol to podstawowy protokół. Wymaga var body: some View. body to opis interfejsu renderowany na GPU.

Czym jest @ViewBuilder i do czego służy?

@ViewBuilder to Result Builder dla wielu Views. Pozwala na if/else, switch, ForEach w kontenerach.

Jaka jest różnica między @StateObject a @ObservedObject?

@StateObject tworzy obiekt. @ObservedObject obserwuje istniejący. @StateObject do pierwszego utworzenia w hierarchii.

Czym jest NavigationStack w iOS 16+?

NavigationStack — nawigacja oparta na danych. path-based, deep linking. Zastępuje NavigationView.

Jak działa @FocusState w SwiftUI?

@FocusState — zarządzanie fokusem wprowadzania. Modyfikator .focused(). Obsługuje enum dla wielu pól.

Podsumowanie

  • View Protocol — var body: some View. Podstawa SwiftUI. Każdy View to struct.
  • @ViewBuilder — deklaratywna składnia dla wielu Views. if/else, ForEach w body.
  • NavigationStack (iOS 16+) — nowoczesna nawigacja. data-driven, path-based.
  • @StateObject — własność modelu. @ObservedObject — obserwacja. @EnvironmentObject — DI.
  • @FocusState — zarządzanie fokusem. Przydatne dla formularzy i wielu pól wprowadzania.
  • .task{} — operacja asynchroniczna z automatycznym anulowaniem. .onAppear{} — synchroniczna.
  • PreviewProvider i Canvas — podglądy w Xcode. @ScaledMetric — adaptacyjne rozmiary.

Opracujemy aplikację mobilną pod klucz

IT Sectr tworzy aplikacje na iOS i Androida dla startupów i firm od 2017 roku. Doradzimy Ci i zaproponujemy najlepsze rozwiązanie.

Omów projekt