SwiftUI — klíčové pojmy, View, State a Data Flow

Autor: IT Sectr Publikováno: 2026-02-21 Doba čtení: 8 min

SwiftUI — deklarativní framework Apple pro tvorbu uživatelských rozhraní na všech platformách ekosystému, představený na WWDC 2019. Na rozdíl od imperativního UIKit s jeho viewDidLoad a ručním obnovováním obrazovky, SwiftUI popisuje UI jako kolekci jednoduchých struktur odpovídajících protokolu View. Podle Swift.org (2025) je SwiftUI používán v 65 % nových projektů publikovaných v App Store. Framework automaticky spravuje aktualizaci rozhraní prostřednictvím mechanismu State a Data Flow — při změně dat je View překresleno bez ručního volání reloadData.

Hlavní body

  • SwiftUI — deklarativní framework Apple pro UI (2019), kde je rozhraní popisováno strukturami odpovídajícími protokolu View.
  • View — základní stavební blok SwiftUI; každé View popisuje svou část obrazovky pomocí computed property body.
  • @State — property wrapper pro ukládání lokálního stavu, při jehož změně se View automaticky překreslí.
  • @Binding — obousměrné propojení mezi View a daty, umožňující potomku View měnit stav rodiče.
  • @ObservedObject a @StateObject — propojení s externími datovými modely pomocí tříd odpovídajících protokolu ObservableObject.

Co je SwiftUI?

SwiftUI — deklarativní UI framework Apple, radikálně odlišný od UIKit. Místo vytváření kontrolerů, pohledů a ruční správy jejich životního cyklu vývojář popisuje rozhraní ve formě deklarací: co by mělo být na obrazovce, ne jak to postavit. SwiftUI je založen na principu reaktivity: rozhraní je funkcí stavu. Při změně stavu (State) SwiftUI automaticky přepočítá body všech závislých View a aktualizuje pouze změněné části obrazovky. SwiftUI je dostupný na iOS 13+, iPadOS 13+, macOS 10.15+, watchOS 6+, tvOS 13+ a visionOS 1+. Kód SwiftUI je multiplatformní: jeden soubor funguje na iPhone, iPad, Mac a Apple Watch s minimálními platformními adaptacemi. Podle Apple WWDC Session 101 (2024) pokrývá SwiftUI více než 90 % standardních UI vzorů App Store.

SwiftUI vs UIKit

UIKit — imperativní framework (2008): vývojář vytvoří UIViewController, nakonfiguruje subviews v viewDidLoad, implementuje delegate/datasource pro UITableView a aktualizuje obrazovku pomocí reloadData nebo setNeedsLayout. SwiftUI nahrazuje kontrolery jednoduchými strukturami View, delegáty — binding a onChange, Auto Layout — HStack/VStack/ZStack s modifikátory (padding, frame, offset). UIKit vyžaduje ruční správu paměti pomocí ARC; SwiftUI — struktury nevyžadující počítání referencí. Výkon SwiftUI je srovnatelný s UIKit: framework používá diffing algoritmus pro minimální sadu změn. V IT Sectr se SwiftUI používá pro nové projekty s cílovým iOS 17+; projekty s podporou iOS 14–15 vyžadují UIKit kvůli omezené kompatibilitě SwiftUI.

Deklarativní syntaxe SwiftUI

Ve SwiftUI je rozhraní popisováno pomocí ViewBuilder — result builder, který transformuje sadu View na tuple nebo Group. Modifikátory (.padding(), .font(), .foregroundColor()) vytvářejí nová View s upravenými nastaveními, nemutují původní objekt. Každý modifikátor vrací nové View, což umožňuje řetězení. ViewBuilder podporuje if/else, switch, ForEach — podmíněné a cyklické vykreslování bez samostatných kontrolerů. View ve SwiftUI je value type (struct), což zaručuje předvídatelné chování a eliminuje race conditions.

Protokol View a computed property body

View — protokol s jediným požadavkem: computed property body typu some View. Každá struktura odpovídající View popisuje svou část obrazovky v body. Typ some View — opaque return type skrývající konkrétní typ vráceného View (kombinace VStack, HStack, ZStack, Text, Image atd.). Kompilátor Swift odvodí konkrétní typ ve fázi kompilace, čímž zachovává výkon přímého volání bez mazání typu.

swift
import SwiftUI

struct GreetingView: View {
    var name: String
    
    var body: some View {
        VStack(spacing: 12) {
            Text("Ahoj, \(name)!")
                .font(.largeTitle)
                .foregroundColor(.primary)
            
            Text("Vítejte v SwiftUI")
                .font(.body)
                .foregroundColor(.secondary)
        }
        .padding()
        .background(
            RoundedRectangle(cornerRadius: 12)
                .fill(.ultraThinMaterial)
        )
    }
}

Struktura GreetingView přijímá parametr name a zobrazuje dva textové bloky ve vertikálním stacku. Modifikátory .font, .foregroundColor, .padding a .background konfigurují vzhled. SwiftUI volá body pokaždé, když se změní vstupní parametry (name) — překreslení probíhá pouze pro změněné části. V příkladu je použito RoundedRectangle s .ultraThinMaterial — nativní blur pozadí vestavěné do SwiftUI.

@State: lokální stav ve SwiftUI

@State — property wrapper deklarující lokální stav patřící jednomu View. SwiftUI automaticky spravuje paměť State: při změně hodnoty je body překresleno, ale pouze pro View používající tento State. State je zdroj pravdy (source of truth) pro jednoduché typy (String, Int, Bool, enum). Nepoužívejte @State pro komplexní datové modely — pro ně jsou určeny @StateObject a @ObservedObject. State by měl být private a uložen v samotném View, ne předáván mezi komponentami.

swift
import SwiftUI

struct CounterView: View {
    @State private var count = 0
    
    var body: some View {
        VStack(spacing: 20) {
            Text("Počet: \(count)")
                .font(.system(size: 48, weight: .bold))
            
            Button(action: { count += 1 }) {
                Label("Zvýšit", systemImage: "plus.circle")
            }
            .buttonStyle(.borderedProminent)
        }
        .padding()
    }
}

Počáteční hodnota count = 0. Každé stisknutí tlačítka zvyšuje count; SwiftUI automaticky překreslí CounterView celé (všechna View). V UIKit by podobný scénář vyžadoval IBOutlet, IBAction a ruční aktualizaci label.text. @State zaručuje, že je View překresleno pouze při změně konkrétního State — diffing algoritmus SwiftUI najde minimální změny ve stromu.

@Binding: obousměrná komunikace mezi View

@Binding — property wrapper vytvářející obousměrné propojení mezi View a daty, která View nevlastní. Binding je reference na State (nebo jiný zdroj pravdy), umožňující potomku View číst a měnit hodnotu uloženou v rodiči. Binding se označuje prefixem $: $count předává Binding<Int> do potomka View. Bez Binding nemůže potomek View změnit data rodiče — může je pouze číst.

swift
import SwiftUI

struct StepperControl: View {
    @Binding var value: Int
    let range: ClosedRange<Int>
    
    var body: some View {
        HStack {
            Button(action: { if value > range.lowerBound { value -= 1 } }) {
                Image(systemName: "minus.circle")
            }
            Text("\(value)")
                .frame(minWidth: 40)
            Button(action: { if value < range.upperBound { value += 1 } }) {
                Image(systemName: "plus.circle")
            }
        }
    }
}

struct ParentView: View {
    @State private var quantity = 5
    
    var body: some View {
        StepperControl(value: $quantity, range: 1...10)
    }
}

ParentView vlastní State quantity a předává Binding prostřednictvím $quantity. StepperControl může měnit value a quantity v rodiči se automaticky synchronizuje. Binding není kopie dat, ale most ke zdroji pravdy. Používejte @Binding pro vlastní ovládací prvky, editory a znovupoužitelné komponenty, které musí měnit data rodiče.

@ObservedObject a @StateObject: externí datové modely

@StateObject — property wrapper pro vytvoření a vlastnictví instance třídy odpovídající ObservableObject. View vytvoří objekt jednou za životní cyklus a překreslí se při změně jeho @Published vlastností. @ObservedObject — podobný wrapper, ale View objekt nevlastní — objekt je vytvořen a uložen mimo View (předán přes inicializátor). Apple doporučuje @StateObject pro zdroj pravdy v hierarchii View a @ObservedObject pro injektáž závislostí.

swift
import SwiftUI
import Combine

class UserSettings: ObservableObject {
    @Published var username: String = "Guest"
    @Published var isLoggedIn = false
}

struct ProfileView: View {
    @StateObject private var settings = UserSettings()
    
    var body: some View {
        VStack {
            TextField("Username", text: $settings.username)
                .textFieldStyle(.roundedBorder)
            
            Toggle("Logged In", isOn: $settings.isLoggedIn)
            
            if settings.isLoggedIn {
                Text("Vítejte, \(settings.username)!")
                    .font(.headline)
            }
        }
        .padding()
    }
}

UserSettings — ObservableObject se dvěma @Published vlastnostmi. ProfileView vlastní objekt prostřednictvím @StateObject. Změna username nebo isLoggedIn automaticky překreslí ProfileView. @Published používá Combine Publisher k oznámení změn SwiftUI. Pro předání settings potomkům View použijte @ObservedObject:

Data Flow ve SwiftUI: kompletní obrázek

Apple definuje čtyři úrovně Data Flow ve SwiftUI: @State (lokální, value type), @Binding (obousměrné), @StateObject/@ObservedObject (reference type s ObservableObject), @EnvironmentObject (globální, injektáž prostřednictvím prostředí). EnvironmentObject umožňuje předávat data přes celou hierarchii View bez explicitního předání v inicializátoru. Dále @AppStorage pracuje s UserDefaults, @SceneStorage — se stavem scény, @FetchRequest — s Core Data. Volba úrovně Data Flow určuje architekturu aplikace: jednoduché obrazovky používají State/Binding, modulární — ObservedObject, rozsáhlé — EnvironmentObject + řešení podobná Redux (TCA, Composable Architecture).

Property WrapperVlastnictvíTypKdy použít
@StateLokálníValue (struct, enum)Jednoduchý stav jednoho View (čítač, toggle, textové pole)
@BindingExterníReference na StatePotomek View měnící data rodiče
@StateObjectVlastnictví ViewReference (class)Zdroj pravdy pro komplexní datový model
@ObservedObjectInjektážReference (class)Model vytvořený mimo View (předán přes init)
@EnvironmentObjectGlobálníReference (class)Data přístupná celé hierarchii (autentizace, téma)

Často kladené otázky

Čím se @State liší od @StateObject?

@State — pro value types (struct, enum, String, Int) a lokální stav jednoho View. SwiftUI automaticky spravuje paměť State. @StateObject — pro reference types (class) odpovídající ObservableObject. @StateObject vlastní objekt a překresluje View při změně @Published vlastností. Pro jednoduché čítače použijte @State; pro modely s logikou — @StateObject.

Lze SwiftUI používat s UIKit?

Ano, SwiftUI se integruje s UIKit prostřednictvím UIHostingController (SwiftUI uvnitř UIKit) a UIViewRepresentable (UIKit uvnitř SwiftUI). UIHostingController zabalí SwiftUI View do UIViewController. UIViewRepresentable umožňuje použití UIKit komponent (MKMapView, WKWebView) ve SwiftUI. Toto je standardní přístup pro migraci projektů z UIKit na SwiftUI.

Co je ViewBuilder ve SwiftUI?

ViewBuilder — result builder (Swift 5.1), který transformuje sadu View na jedinou hodnotu typu TupleView, Group nebo ConditionalContent. ViewBuilder umožňuje psát imperativní if/else a switch uvnitř deklarativního body. Bez ViewBuilder by bylo nutné vracet AnyView nebo Group pro každý podmíněný blok. ViewBuilder je důvod, proč v body není potřeba čárka mezi View.

Funguje SwiftUI na všech zařízeních Apple?

Ano, SwiftUI podporuje iOS 13+, iPadOS 13+, macOS 10.15+, watchOS 6+, tvOS 13+ a visionOS 1+. Některá API jsou však dostupná pouze na novějších verzích: například navigationStack (iOS 16+), Observable macro (iOS 17+). Pro zpětnou kompatibilitu použijte #available a UIKit adaptace.

Jak ladit aplikace SwiftUI?

Xcode Debug View Hierarchy zobrazuje strom SwiftUI View s modifikátory a rámečky. Nástroj SwiftUI Inspector (pravý panel Xcode) umožňuje měnit modifikátory v reálném čase. self._printChanges() v body loguje příčiny překreslení. Instruments se šablonou SwiftUI sleduje výkon View a detekuje nadměrná překreslení.

Shrnutí

  • SwiftUI — deklarativní framework Apple pro UI, kde je rozhraní popisováno strukturami View s computed property body (2019).
  • View — value type (struct) odpovídající protokolu View; body vrací some View prostřednictvím ViewBuilder.
  • @State — lokální stav pro value types; při změně se View automaticky překreslí.
  • @Binding — obousměrné propojení pomocí prefixu $; potomek View mění data rodiče.
  • @StateObject / @ObservedObject — reference types s ObservableObject a @Published vlastnostmi; StateObject vlastní objekt, ObservedObject přijímá zvenčí.
  • @EnvironmentObject — globální stav pro celou hierarchii View; injektován pomocí .environmentObject().
  • Data Flow ve SwiftUI — od State (lokální) přes Binding (obousměrný) k ObservedObject (modulární) a EnvironmentObject (globální).

Vyvineme mobilní aplikaci na klíč

IT Sectr vytváří aplikace pro iOS a Android pro startupy a podniky od roku 2017. Poradíme vám a navrhneme nejlepší řešení.

Prodiskutovat projekt

Přečtěte si také