.onAppear — modifikátor SwiftUI, který provádí uzávěr při přidávání View do hierarchie rozhraní. Volání proběhne jednou za výskyt instance na obrazovce a slouží jako hlavní bod pro načítání dat, spouštění animací a odesílání analytických událostí. Podle Apple Developer Documentation (2026) onAppear zaručuje provedení před prvním vykreslením, ale nezaručuje volání při každém opakovaném zobrazení, pokud View zůstává v paměti. Více o SwiftUI si přečtěte v materiálu o SwiftUI.
Hlavní body
.onAppear — modifikátor View ve SwiftUI, který přijímá uzávěr Void a provádí jej v okamžiku, kdy se View stane viditelným na obrazovce. Tento modifikátor je součástí systému životního cyklu komponent SwiftUI spolu s .onDisappear a .task. Apple představila onAppear spolu s vydáním SwiftUI v iOS 13 a watchOS 6 jako náhradu za viewDidLoad z UIKit.
.onAppear modifikuje libovolné View a vrací stejné View s připojenou akcí. Kompilátor SwiftUI volá předaný uzávěr jednou, když je pohled přidán do hierarchie a projde fází vykreslení. Pokud je View smazáno a poté znovu přidáno (například při posouvání v seznamu), onAppear je volán znovu — toto chování se často stává zdrojem neočekávaných chyb.
Základní syntaxe modifikátoru je minimalistická: onAppear bez parametrů. Ve SwiftUI není možnost předat prioritu nebo animaci — uzávěr se provádí synchronně v hlavním vlákně ihned po vykreslení.
struct ContentView: View {
var body: some View {
Text("Ahoj SwiftUI!")
.onAppear {
print("View se objevilo na obrazovce")
}
}
}
Omezení: onAppear nepodporuje přímo async/await. Pro asynchronní operace uvnitř uzávěru je potřeba Task {} nebo samostatná funkce async/await volaná přes Task.detached. To činí onAppear méně pohodlným pro síťové požadavky ve srovnání s modifikátorem .task.
.onAppear se začleňuje do vykreslovací pipeline SwiftUI ve fázi layout+render. Když SwiftUI vypočítá tělo View a detekuje změnu hierarchie, spustí callbacky onAppear pro všechny nově přidané pohledy. Pořadí volání odpovídá pořadí vnoření: nejprve onAppear u rodiče, poté u potomků.
Důležitá vlastnost SwiftUI — onAppear není vázán na fyzický výskyt na obrazovce. Modifikátor je volán, když je View přidáno do hierarchie, bez ohledu na to, zda je viditelné pro uživatele (např. mimo obrazovku v ScrollView). To odlišuje SwiftUI od UIKit, kde viewWillAppear funguje pouze při skutečném zobrazení.
Pořadí volání se řídí pravidlem parent-first: VStack nebo NavigationView nejprve obdrží onAppear, poté každý potomek v pořadí. To je kritické pro inicializaci sdílených zdrojů: pokud potomci závisí na datech načítaných rodičem, musí zkontrolovat dostupnost přes Optional.
struct ParentView: View {
var body: some View {
VStack {
ChildView()
ChildView()
}
.onAppear {
print("Parent onAppear — první")
}
}
}
struct ChildView: View {
var body: some View {
Text("Dítě")
.onAppear {
print("Child onAppear")
}
}
}
Výstup do konzole bude: Parent onAppear — první, poté dvakrát Child onAppear v pořadí pozice. Toto chování je garantováno Apple a stabilní ve všech verzích SwiftUI (iOS 13–18).
.onAppear má několik scénářů volání, které závisí na kontejneru a navigaci. V NavigationStack se onAppear spouští při každém push nového ovladače a při pop — pro kořenový ovladač. V TabView přepínání karet volá onAppear pro zobrazenou kartu a onDisappear pro skrytou.
V List a ScrollView je onAppear volán pro buňky, které vstoupily do oblasti viditelnosti nebo jsou v bufferu předvykreslení. iOS 18 zavedl mechanismus prefetch, který může volat onAppear pro buňky 2–3 obrazovky před posouváním — to zrychluje vnímání, ale může způsobovat zbytečné síťové požadavky.
NavigationStack (iOS 16+) spravuje zásobník obrazovek jinak než NavigationView. Při push nové obrazovky se onAppear aktivuje pouze na nové obrazovce a aktuální obrazovka neobdrží onDisappear až do skutečného smazání. Při pop probíhá opačný proces: onDisappear na opouštěné obrazovce, onAppear na vracející se.
| Scénář | onAppear | onDisappear |
|---|---|---|
| Push | Nová obrazovka | Ne (obrazovka zůstává v zásobníku) |
| Pop | Vracející se obrazovka | Opouštěná obrazovka |
| Přepnutí karty | Nová karta | Stará karta |
| Zavření sheetu | Rodičovská obrazovka | Otevřený sheet |
Praktické použití onAppear zahrnuje tři hlavní kategorie: načítání dat, spouštění animací a odesílání analytiky. Každý scénář vyžaduje zohlednění charakteristik životního cyklu SwiftUI, aby se předešlo duplicitním voláním a únikům paměti.
Načítání dat — nejčastější scénář onAppear. Uvnitř uzávěru je vytvořen Task pro async volání a výsledek je uložen v @State nebo @StateObject. Je důležité zkontrolovat, zda data nejsou načítána znovu, pomocí flagu isLoading nebo kontroly nil.
struct ProfileView: View {
@StateObject private var viewModel = ProfileViewModel()
var body: some View {
VStack {
if viewModel.isLoading {
ProgressView()
} else {
Text(viewModel.userName)
}
}
.onAppear {
guard viewModel.userName == nil else { return }
Task {
await viewModel.loadProfile()
}
}
}
}
Guard against re-fetch — kritická praxe. Pokud SwiftUI znovu vytvoří View (například při otočení obrazovky), onAppear bude bez guardu znovu volán. Alternativou je modifikátor .task, který automaticky ruší předchozí požadavek.
Vstupní animace používá onAppear ke změně stavových proměnných, které spouštějí animaci přes withAnimation nebo modifikátor animation. Typický vzor: počáteční stav (opacity 0, offset 100), přechod do konečného (opacity 1, offset 0) při zobrazení.
struct AnimatedCard: View {
@State private var isVisible = false
var body: some View {
RoundedRectangle(cornerRadius: 12)
.fill(Color.blue)
.opacity(isVisible ? 1 : 0)
.offset(y: isVisible ? 0 : 50)
.animation(.spring(), value: isVisible)
.onAppear {
withAnimation(.spring().delay(0.3)) {
isVisible = true
}
}
}
}
Zpoždění 0,3 vteřiny vytváří efekt postupného zobrazování, pokud je na obrazovce několik takových karet. Pro seznam animovaných prvků použijte index prvku jako násobič zpoždění.
.task — modifikátor SwiftUI přidaný v iOS 15, který řeší problém asynchronních operací v onAppear. Na rozdíl od onAppear .task přijímá async uzávěr, automaticky spravuje jeho životní cyklus a ruší jej při zmizení View. Zatímco onAppear se provádí synchronně, .task spouští asynchronní operaci a umožňuje SwiftUI ji zrušit při onDisappear.
Hlavní rozdíl — správa rušení. Když .task vytvoří async operaci, SwiftUI uchovává odkaz na Task a automaticky volá cancel() při odstranění View z hierarchie. onAppear s Task {} uvnitř nezruší spuštěnou operaci — ta pokračuje v provádění i poté, co View zmizí, což může způsobit závodní stav nebo zápis do již uvolněné instance.
| Vlastnost | .onAppear | .task |
|---|---|---|
| Verze iOS | iOS 13+ | iOS 15+ |
| Async podpora | Pouze přes Task {} | Nativní async/await |
| Automatické rušení | Ne | Při zmizení View |
| Opakované volání | Při každém zobrazení | Výchozí jednou |
| Synchromní kód | Ano | Pouze async |
Výběr modifikátoru: pro synchronní akce (animace, analytika, logy) použijte onAppear. Pro asynchronní načítání dat (API, Core Data, souborový systém) je .task preferovaný — bezpečnější a čistější.
Chyba 1: vícenásobné volání kvůli přetvoření View. Když SwiftUI znovu vytvoří tělo View (změna @State, otočení obrazovky), onAppear může být volán znovu. Řešení — přidání flagu načítání nebo použití .equatable() k zabránění zbytečným překreslením. Podle SwiftLee (2025) 40% chyb SwiftUI v produkci souvisí právě s opakovanými voláními onAppear.
Chyba 2: únik paměti přes silný odkaz. Pokud uzávěr onAppear zachytí self bez slabého odkazu, vznikne retain cycle s View. SwiftUI nezaručuje vynulování zachycených objektů při zmizení View. Použijte capture list [weak self] pro ViewModel nebo služby.
Chyba 3: provedení v pozadí vlákna. onAppear se provádí v hlavním vlákně — to je správné pro UI operace. Ale pokud je uvnitř onAppear spuštěn Task, ujistěte se, že aktualizace @State probíhá přes MainActor.run. Swift 5.9 a vyšší se automaticky vracejí na MainActor, ale je lepší explicitně uvést @MainActor.
Vzor s flagem načítání je nejspolehlivější způsob ochrany před duplikováním. Uchovávejte flag v @State nebo @StateObject a resetujte jej pouze při ruční aktualizaci. Alternativa — použití .task místo onAppear: .task se výchozí nespouští znovu při překreslení, pokud async operace již běží.
struct SafeView: View {
@State private var hasAppeared = false
@State private var items: [Item] = []
var body: some View {
List(items, id: \.id) { item in
Text(item.name)
}
.onAppear {
guard !hasAppeared else { return }
hasAppeared = true
Task {
items = await DataService.shared.fetchItems()
}
}
}
}
Často kladené otázky
viewDidLoad je volán jednou za život UIViewController, nezávisle na viditelnosti. .onAppear je volán při každém přidání View do hierarchie — pokud je View smazáno a znovu přidáno, onAppear se znovu aktivuje. V NavigationView je viewDidLoad volán při inicializaci a onAppear — při každém zobrazení obrazovky.
Ano, přes obal Task { await asyncFunction() }. Nicméně pro async operace je preferován .task, protože automaticky spravuje rušení a nevyžaduje ruční vytváření Task. .task také garantuje zrušení při zmizení View, čímž předchází únikům.
Příčinou je přetvoření těla View kvůli změně @State, @Published nebo konfigurace předka. SwiftUI může překreslit View jako reakci na změnu libovolné pozorovatelné vlastnosti. Navíc LazyVStack a List volají onAppear pro buňky, které se přibližují k viditelné oblasti, a znovu při posouvání nahoru.
Ano, .onAppear je dostupný na všech platformách SwiftUI: iOS 13+, watchOS 6+, tvOS 13+, macOS 10.15+. Chování je identické: modifikátor je volán při přidání View do hierarchie. Na watchOS se onAppear spouští při aktivaci aplikace z pohotovostního režimu, což je třeba zohlednit v návrhu.
.onAppear nepřijímá parametry — pouze Void uzávěr. Pro předání parametrů použijte uzávěr, který zachycuje externí proměnné. Alternativní přístup — vytvoření vlastního onAppear modifikátoru s parametry přes ViewModifier nebo analog .onChange.
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é