SwiftUI je deklarativní framework od Applu pro vytváření uživatelských rozhraní na všech platformách ekosystému. Namísto imperativního popisu kroků vývojář deklaruje, jak má rozhraní vypadat, a SwiftUI spravuje jeho vykreslování a aktualizaci. Podle Apple Developer Documentation (2025) SwiftUI podporuje iOS 15+, iPadOS 15+, macOS 12+, watchOS 8+ a tvOS 15+ a používá View Protocol jako základní stavební blok pro všechny komponenty rozhraní.
Hlavní body
body — základ každé UI komponenty SwiftUI, vracející popis obrazovky prostřednictvím kompozice pohledů.SwiftUI je deklarativní framework, představený Applem v roce 2019 jako náhrada UIKit v nových projektech. Místo ručního vytváření instancí UIView a jejich přidávání do hierarchie vývojář popisuje rozhraní prostřednictvím struktur implementujících protokol View. SwiftUI automaticky vypočítá rozdíl mezi aktuálním a novým stavem a překreslí pouze změněné části pomocí vlastního vykreslovacího jádra.
Framework je napsán ve Swiftu s použitím value semantics (struktury, ne třídy), což činí UI komponenty lehkými a bezpečnými pro vlákna. Na rozdíl od UIKit, kde UIViewController může vážit 200+ bajtů kvůli Objective-C runtime, SwiftUI View je jen struktura o velikosti několika bajtů. To je obzvláště důležité pro watchOS s jeho omezenou pamětí.
Stejný popis View funguje na iPhone, iPad, Mac, Apple Watch, Apple TV a Apple Vision Pro. SwiftUI přizpůsobuje rozhraní platformě: na iOS — dotyková gesta, na macOS — klávesové zkratky, na watchOS — rolování Digital Crown. To zkracuje dobu vývoje pro společnosti vydávající aplikace na více platforem Apple, ale vyžaduje dodatečnou konfiguraci pro specifické prvky každé platformy.
Ve SwiftUI je každá obrazovka strukturou implementující protokol View s jediným požadavkem: computed property body typu some View. Klíčové slovo some (opaque type) skrývá konkrétní typ pohledu a umožňuje SwiftUI optimalizovat vykreslování. Uvnitř body vývojář kombinuje hotové komponenty — Text, Image, Button, List — pomocí ViewBuilder, který shromažďuje několik pohledů do jednoho.
struct GreetingView: View {
let name: String
var var body: some View {
VStack {
Text("Ahoj, \(name)!")
.font(.title)
.foregroundColor(.blue)
Image(systemName: "hand.wave")
.imageScale(.large)
}
.padding()
}
}
V příkladu VStack (vertikální zásobník) obsahuje Text a Image. Hodnota name je předávána přes inicializátor struktury — tak funguje DI (Dependency Injection) ve SwiftUI bez externích DI kontejnerů. Každý modifikátor vrací nový pohled s aplikovanou změnou, aniž by mutoval originál. To je možné díky neměnnosti (immutability) hodnotových typů.
ViewBuilder je result builder, anotovaný @resultBuilder, který shromažďuje až 10 pohledů do jednoho. Uvnitř body lze použít if/else, switch a ForEach bez dalších obalů. ForEach pracuje s prvky Identifiable — každý pohled dostává unikátní id pro správnou animaci při vkládání/mazání.
Ve SwiftUI stav určuje, jaký obsah se na obrazovce zobrazuje. Když se stav změní, SwiftUI znovu vytvoří body závislého pohledu a porovná výsledek s předchozím pomocí diff algoritmu. Pro ukládání stavu se používají property wrappers — každý řeší svůj úkol: lokální stav, propojení s podřízeným pohledem nebo externí datový model.
struct CounterView: View {
@State private var count = 0
var var body: some View {
VStack {
Text("Počítadlo: \(count)")
Button("Zvýšit") {
count += 1
}
}
}
}
class UserViewModel: ObservableObject {
@Published var name = ""
@Published var age = 0
}
@State ukládá lokální jednoduchou hodnotu (Int, String, Bool) uvnitř struktury View. SwiftUI přesouvá paměť ze struktury do samostatného úložiště — proto lze vlastnost s @State měnit (mutovat), i když je View hodnotový typ. @ObservableObject — pro třídy s vlastnostmi @Published, jejichž změny automaticky informují SwiftUI o potřebě překreslení.
@Binding vytváří obousměrné spojení se zdrojem dat umístěným v nadřazeném pohledu. Rodič předává $variable (projected value), dítě čte a zapisuje hodnotu prostřednictvím binding. To umožňuje přesunout vstup textu nebo přepínač do samostatné komponenty při zachování stavu v rodiči. Bez @Binding by každá změna vyžadovala callback uzávěr pro předání nové hodnoty nahoru.
Před iOS 16 byla navigace ve SwiftUI postavena na NavigationView — zastaralém API se složitým chováním na iPadu (split view, double column). Od iOS 16 Apple doporučuje NavigationStack — zjednodušenou alternativu s typově bezpečnými trasami. Vývojář definuje enum možných tras a NavigationStack automaticky spravuje zásobník obrazovek s podporou hlubokých odkazů a návratu ke kořenu.
enum Route: Hashable {
case detail(id: Int)
case settings
}
struct ContentView: View {
var var body: some View {
NavigationStack {
List {
NavigationLink("Obrazovka detailů",
value: Route.detail(id: 42))
NavigationLink("Nastavení",
value: Route.settings)
}
.navigationDestination(for: Route.self) { route in
switch route {
case .detail(let id): DetailView(id: id)
case .settings: SettingsView()
}
}
}
}
}
Trasy typu Route: Hashable umožňují použití libovolného datového typu pro předávání parametrů. navigationDestination(for:destination:) spojuje typ trasy s cílovým pohledem. Výhoda oproti UIKit navigaci — překreslení není nutné při přidání nové trasy: stačí přidat case do enumu a handler do switch. Hluboké odkazy jsou zpracovávány přes processDeepLink na NavigationStack.
Pro programový přechod (po přihlášení, časovači nebo odpovědi serveru) se používá @State s inicializátorem NavigationLink: NavigationLink(isActive: $isActive). Při nastavení isActive = true dojde k přechodu bez dotyku uživatele. Alternativa — binding pole $path v NavigationStack: $path.append(Route.detail(id: 1)).
Modifier je metoda vracející modifikovanou kopii pohledu. Na rozdíl od UIKit, kde se konfigurace vlastností provádí mutací existujícího pohledu, SwiftUI vytváří novou hodnotu s aplikovanou změnou. Řetězec modifikátorů (chaining) staví konečné rozhraní z postupných transformací: písmo → mezera → barva → stín → gesto.
Apple poskytuje více než 200 vestavěných modifikátorů. Nejčastější jsou: .font(), .foregroundColor(), .padding(), .background(), .cornerRadius(), .shadow(), .opacity(), .offset(). Pořadí modifikátorů je důležité: .padding() před .background() obarví oblast s mezerou, po — pouze vnitřní oblast. Vlastní modifikátory se vytvářejí prostřednictvím protokolu ViewModifier.
Modifikátory lze použít podmíněně pomocí ternárního operátoru: .foregroundColor(isError ? .red : .primary). Pro animaci se používá .animation(.easeInOut, value: state) — modifikátor animace se váže na konkrétní vlastnost stavu. Při změně této vlastnosti SwiftUI animuje přechod mezi starou a novou hodnotou. Animace funguje s opacity, offset, scale, rotation, velikostí a barvou — pro každou vlastnost je definován odpovídající AnimatableParameter.
Pro vlastní animace jsou k dispozici .transition (objevení/zmizení) a .matchedGeometryEffect (plynulý přechod prvku mezi dvěma kontejnery). Poslední jmenovaný se používá pro hero-animace v seznamech: ikona v buňce seznamu se plynule změní na velký obrázek na obrazovce detailů.
Volba mezi SwiftUI a UIKit je jedním z prvních dilemat iOS vývojáře. Oba frameworky jsou podporovány Applem, ale řeší úkol vytváření rozhraní zásadně odlišnými způsoby: SwiftUI deklarativně, UIKit imperativně. Rozdíl se projevuje ve správě stavu, navigaci, výkonu a kompatibilitě.
| Aspekt | SwiftUI | UIKit |
|---|---|---|
| Přístup | Deklarativní: co zobrazit | Imperativní: jak postavit |
| Stav | Property Wrappers, automatické překreslení | Ručně: reloadData, setNeedsLayout |
| Kód UI | Kompaktní, řetězce modifikátorů | Objemný, NSCoder/Storyboard/omezení |
| Výkon | Vysoký na iOS 17+, diff algoritmus | Špičkový na iOS 12–16, přímá kontrola |
| Minimální verze | iOS 15+ (plná podpora) | iOS 2+ (všechny verze) |
Pro nové projekty s minimální verzí iOS 17 Apple doporučuje SwiftUI jako primární framework. UIKit zůstává nezbytný pro rozhraní vyžadující jemnou kontrolu nad vykreslováním (vlastní UICollectionViewLayout, složité CAAnimation scény) nebo podporu iOS 12–14. Mnoho projektů používá hybridní přístup: SwiftUI je prostřednictvím UIHostingController vložen do UIKit aplikace a UIViewRepresentable umožňuje použití UIKit komponent uvnitř SwiftUI hierarchie.
Často kladené otázky
Ano, pomocí UIHostingController (SwiftUI v UIKit) a UIViewRepresentable (UIKit ve SwiftUI). Jedná se o hybridní přístup, populární při migraci.
iOS 17 — plná funkčnost: NavigationStack, Observation framework, Swift Charts. iOS 15 — minimální práh pro produkci.
Nejčastější příčinou je změna vlastnosti @Published na pozadí. ObservableObject musí odesílat změny na main actor: @MainActor class ViewModel.
Použijte .debounce přes Combine: Button.publisher(for: .tap) .debounce(for: .seconds(0.3), scheduler: RunLoop.main).
Ano, pomocí Gesture modifikátorů: DragGesture, LongPressGesture, MagnificationGesture, RotationGesture. Kombinujte je přes .simultaneousGesture() a .sequenced().
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é