NavigationStack är en modern navigationscontainer i SwiftUI, introducerad i iOS 16+ och som ersätter NavigationView. Enligt Apple Developer Documentation, 2024 hanterar NavigationStack skärmstacken via en typ säker navigationsväg (NavigationPath), stödjer djupnavigering, programmatisk återgång till rotskärmen och bevarande av tillstånd vid dataändringar. Till skillnad från NavigationView kräver NavigationStack ingen inpackning i en extra container och erbjuder en direkt Bindning till navigationsvägen.
Huvudsaken
NavigationStack är ett container-View som implementerar stackbaserad navigering (LIFO). Den hanterar övergångshistorik, låter dig placera nya skärmar på stacken och återvända via systemknappen «Tillbaka» eller programmatiskt. NavigationStack är en del av SwiftUI från och med iOS 16, iPadOS 16, macOS 13, watchOS 9 och tvOS 16.
Den viktigaste innovationen i NavigationStack är den typ säkra navigationsvägen. Istället för att direkt ange destination när du skapar NavigationLink, placerar du ett värde (value) i vägen, och registreringen av mål-View sker separat via modifieraren .navigationDestination(for:destination:). Detta separerar navigering och visning, vilket gör koden mer modulär och testbar.
Enligt WWDC 2022 (Session 10054) använder NavigationStack en ny navigationsmekanism baserad på ObservableObject och SwiftUI-livscykeln. Till skillnad från NavigationView som förlitade sig på UINavigationController under huven, är NavigationStack helt implementerad i SwiftUI, vilket förbättrar förutsägbarheten och kompatibiliteten med SwiftUI-livscykeln.
NavigationStack accepterar ett rot-View och en valfri navigationsväg (Bindning till NavigationPath eller en array av Hashable-värden). Alla underordnade skärmar placeras i stacken via NavigationLink eller programmatisk tilläggning av värden till vägen.
NavigationView var den primära navigationscontainern i SwiftUI fram till iOS 16. Den hanterade automatiskt UINavigationController under huven, vilket ledde till en rad problem: oförutsägbart beteende vid dataändringar, svårigheter med programmatisk navigering och brist på typ säkerhet.
| Egenskap | NavigationStack (iOS 16+) | NavigationView (iOS 13–15) |
|---|---|---|
| Navigeringstyp | Stack (LIFO) | Stack (LIFO) |
| Navigationsväg | Typad (NavigationPath) | Stöds inte |
| Deep linking | Inbyggt stöd | Kräver hack |
| Programmatisk återgång | Via väg (pop, popToRoot) | dismiss, presentationMode |
| Under huven | SwiftUI native | UINavigationController |
| Kompatibilitet | iOS 16+ | iOS 13+ |
Viktigaste fördelen med NavigationStack — typ säker navigering. Du definierar vägen som en array av konkreta typer (eller NavigationPath för heterogena stackar) och registrerar destination för varje typ. Detta eliminerar typmissmatchfel och gör navigeringen förutsägbar.
NavigationView är föråldrad i iOS 17. Apple rekommenderar migrering till NavigationStack för alla nya projekt och vid uppdatering av minimiversionen till iOS 16.
NavigationPath är en typ som representerar navigationsvägen i NavigationStack. Den kan lagra heterogena värden (AnyHashable) eller användas med en konkret typ via Bindning till en array [T: Hashable]. NavigationPath kodas och avkodas automatiskt för att bevara tillståndet.
struct ContentView: View {
@State private var path = NavigationPath()
var body: some View {
NavigationStack(path: $path) {
HomeView()
.navigationDestination(for: String.self) { value in
DetailView(id: value)
}
.navigationDestination(for: Int.self) { value in
NumberView(number: value)
}
}
}
func goToRoot() {
path.removeLast(path.count)
}
func pushDeepLink() {
path.append("detail_42")
}
}
Heterogen stack: NavigationPath kan innehålla värden av olika typer om de implementerar Hashable. Till exempel kan den första skärmen acceptera String (ID), den andra — Int (nummer), den tredje — en anpassad enum Route. För visning av varje typ registreras en separat .navigationDestination.
Codable stöd: NavigationPath implementerar Codable om alla värden i vägen också är Codable + Hashable. Detta gör det möjligt att spara och återställa navigeringstillståndet vid omstart av appen eller vid växling till bakgrunden.
.navigationDestination(for:destination:) — en modifierare som registrerar mål-View för en specifik datatyp. När NavigationLink placerar ett värde av denna typ i vägen, hittar SwiftUI automatiskt motsvarande .navigationDestination och skapar skärmen.
enum AppRoute: Hashable {
case profile(UserID)
case settings
case about
}
struct AppNavigation: View {
@State private var path = NavigationPath()
var body: some View {
NavigationStack(path: $path) {
HomeView()
.navigationDestination(for: AppRoute.self) { route in
switch route {
case .profile(let id):
ProfileView(userId: id)
case .settings:
SettingsView()
case .about:
AboutView()
}
}
}
}
}
// Navigate: path.append(AppRoute.profile("user_123"))
Viktig regel: .navigationDestination måste tillämpas på ett View som finns inuti NavigationStack, och innan NavigationLink placerar ett värde i vägen. Vanligtvis läggs den till rot-View eller till sektionens container. Om .navigationDestination inte hittas för värdetypen, sker ingen övergång.
Enligt SwiftUI Engineering (2023) kan .navigationDestination registreras på olika nivåer i hierarkin. SwiftUI söker efter den närmaste passande destination vid ett navigeringsförsök. Detta gör det möjligt att åsidosätta destination för en typ i olika delar av appen.
Mönster 1: navigering via enum Route. Definiera en enum med associerade värden för alla skärmar i appen. Använd en .navigationDestination för AppRoute och switch för routning. Detta ger en enda källa till sanning för alla möjliga övergångar i appen.
struct StoreView: View {
@State private var path: [ProductRoute] = []
var body: some View {
NavigationStack(path: $path) {
ProductGrid()
.navigationDestination(for: ProductRoute.self) { route in
switch route {
case .detail(let product):
ProductDetail(product: product)
case .reviews(let productId):
ReviewsView(productId: productId)
}
}
}
}
}
enum ProductRoute: Hashable {
case detail(Product)
case reviews(String)
}
Mönster 2: programmatisk navigering och deep linking. NavigationStack möjliggör programmatisk hantering av stacken: lägga till, ta bort skärmar och återvända till roten. Detta är nödvändigt för push-notiser, djupa länkar och återställning av navigering efter omstart.
Mönster 3: array av typer istället för NavigationPath. Om alla skärmar använder en typ (t.ex. String eller en anpassad enum), använd Bindning till [T]. Detta ger striktare typning och bättre prestanda än NavigationPath. NavigationPath är motiverad för heterogena stackar med olika skärmtyper.
Enligt Point-Free (2024) är NavigationStack med enum Route det föredragna sättet att organisera navigering i SwiftUI-appar. Det gör alla möjliga övergångar explicita, typ säkra och testbara, vilket är särskilt viktigt för stora projekt med dussintals skärmar.
Vanliga frågor
NavigationStack — en SwiftUI navigationscontainer (iOS 16+) som hanterar skärmstacken via en typ säker väg. Den har ersatt NavigationView och erbjuder stöd för deep linking, programmatisk navigering och tillståndslagring.
NavigationStack använder en typ säker väg (NavigationPath) istället för direkt koppling av NavigationLink med destination. Den stödjer programmatisk navigering, deep linking och Codable för tillståndslagring. Den fungerar på SwiftUI, inte via UINavigationController.
NavigationPath är en typ som representerar sekvensen av skärmar i stacken. Du lägger till värden i vägen via path.append() eller via NavigationLink med value. För visning av varje typ registreras .navigationDestination. NavigationPath stödjer Codable och automatisk tillståndslagring.
Via programmatisk väghantering: efter bearbetning av URL, anropa path.append() med motsvarande rutvärde. NavigationStack visar automatiskt målskärmen. Återgång till roten — path.removeLast(path.count).
Ja, om din minimiversion är iOS 16+. NavigationView är föråldrad i iOS 17. Migrering ger typ säker navigering, deep linking-stöd och bättre anpassning till SwiftUI-livscykeln. För projekt med iOS 15 och lägre, använd fortfarande NavigationView.
Sammanfattning
Vi utvecklar en mobil applikation nyckelfärdigt
IT Sectr skapar iOS- och Android-applikationer för startups och företag sedan 2017. Vi ger dig råd och föreslår den bästa lösningen.
Läs också