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í 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.
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.
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.
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.
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 — 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.
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 — 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.
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.
@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í.
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:
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 Wrapper | Vlastnictví | Typ | Kdy použít |
|---|---|---|---|
| @State | Lokální | Value (struct, enum) | Jednoduchý stav jednoho View (čítač, toggle, textové pole) |
| @Binding | Externí | Reference na State | Potomek View měnící data rodiče |
| @StateObject | Vlastnictví View | Reference (class) | Zdroj pravdy pro komplexní datový model |
| @ObservedObject | Injektáž | Reference (class) | Model vytvořený mimo View (předán přes init) |
| @EnvironmentObject | Globální | Reference (class) | Data přístupná celé hierarchii (autentizace, téma) |
Často kladené otázky
@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.
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.
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.
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.
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í
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í.
Přečtěte si také