NavigationStack egy modern navigációs konténer a SwiftUI-ban, amelyet az iOS 16+-ban mutattak be és lecserélte a NavigationView-t. A Apple Developer Documentation, 2024 szerint a NavigationStack egy típusbiztos navigációs út (NavigationPath) keresztül kezeli a képernyők vermét, támogatja a mély navigációt, a programozott visszatérést a győképernyőre és az állapot megtartását adatváltozáskor. A NavigationView-val ellentétben a NavigationStack nem igényel további konténerbe csomagolást és közvetlen Binding-et biztosít a navigációs úthoz.
Főbb pontok
NavigationStack egy konténer View, amely verem (LIFO) alapú navigációt valósít meg. Kezeli az átmenetek előzményeit, lehetővé teszi új képernyők elhelyezését a veremben és visszatérést a rendszer «Vissza» gombjával vagy programozottan. A NavigationStack a SwiftUI része az iOS 16, iPadOS 16, macOS 13, watchOS 9 és tvOS 16 óta.
A NavigationStack fő újítása a típusbiztos navigációs út. Ahelyett, hogy közvetlenül célpointot adna meg a NavigationLink létrehozásakor, értéket (value) helyez el az útban, és a cél View regisztrálása külön történik a .navigationDestination(for:destination:) módosítón keresztül. Ez szétválasztja a navigációt és a megjelenítést, modulárisabbá és tesztelhetőbbé téve a kódot.
A WWDC 2022 (Session 10054) szerint a NavigationStack új, ObservableObject-en és SwiftUI életcikluson alapuló navigációs mechanizmust használ. A NavigationView-val ellentétben, amely a UINavigationController-re támaszkodott a motorháztető alatt, a NavigationStack teljesen a SwiftUI-ban van megvalósítva, ami javítja a kiszámíthatóságot és a SwiftUI életciklussal való kompatibilitást.
A NavigationStack fogad egy gyökér View-t és egy opcionális navigációs útvonalat (Binding a NavigationPath-hez vagy Hashable értékek tömbjéhez). Az összes gyermek képernyő a verembe kerül a NavigationLink-en vagy értékek programozott hozzáadásán keresztül az útvonalhoz.
NavigationView volt a SwiftUI fő navigációs konténere az iOS 16-ig. Automatikusan kezelte a UINavigationController-t a motorháztető alatt, ami számos problémához vezetett: kiszámíthatatlan viselkedés adatváltozáskor, nehézségek a programozott navigációval és a típusbiztonság hiánya.
| Jellemző | NavigationStack (iOS 16+) | NavigationView (iOS 13–15) |
|---|---|---|
| Navigáció típusa | Verem (LIFO) | Verem (LIFO) |
| Navigációs út | Típusos (NavigationPath) | Nem támogatott |
| Deep linking | Beépített támogatás | Hekkeket igényel |
| Programozott visszatérés | Útvonalon keresztül (pop, popToRoot) | dismiss, presentationMode |
| Motorháztető alatt | SwiftUI native | UINavigationController |
| Kompatibilitás | iOS 16+ | iOS 13+ |
Fő előny NavigationStack — típusbiztos navigáció. Az útvonalat konkrét típusú tömbként (vagy NavigationPath-ként heterogén vermekhez) definiálja és regisztrálja a destination-t minden típushoz. Ez kiküszöböli a típus-eltérési hibákat és kiszámíthatóvá teszi a navigációt.
A NavigationView elavult az iOS 17-ben. Az Apple a NavigationStack-re való áttérést ajánlja minden új projekthez és a minimális verzió iOS 16-ra frissítésekor.
NavigationPath egy típus, ami a navigációs útvonalat képviseli a NavigationStack-ben. Tárolhat heterogén értékeket (AnyHashable) vagy használható konkrét típussal a [T: Hashable] tömbhöz kötött Binding-en keresztül. A NavigationPath automatikusan kódolódik és dekódolódik az állapot megtartása érdekében.
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")
}
}
Heterogén verem: A NavigationPath különböző típusú értékeket tartalmazhat, ha azok megvalósítják a Hashable-t. Például az első képernyő fogadhat String (ID)-t, a második — Int (számot), a harmadik — egy egyedi enum Route-ot. Minden típus megjelenítéséhez külön .navigationDestination kerül regisztrálásra.
Codable támogatás: A NavigationPath megvalósítja a Codable-t, ha az útvonalban lévő összes érték szintén Codable + Hashable. Ez lehetővé teszi a navigációs állapot mentését és visszaállítását az alkalmazás újraindításakor vagy háttérbe kapcsoláskor.
.navigationDestination(for:destination:) — egy módosító, ami regisztrálja a cél View-t egy adott adattípushoz. Amikor a NavigationLink egy ilyen típusú értéket helyez az útvonalba, a SwiftUI automatikusan megtalálja a megfelelő .navigationDestination-t és létrehozza a képernyőt.
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"))
Fontos szabály: A .navigationDestination-t arra a View-ra kell alkalmazni, amely a NavigationStack-en belül van, és mielőtt a NavigationLink értéket helyezne az útvonalba. Általában a gyökér View-hoz vagy a szakasz konténeréhez adják hozzá. Ha a .navigationDestination nem található az érték típusához, az átmenet nem történik meg.
A SwiftUI Engineering (2023) szerint a .navigationDestination a hierarchia különböző szintjein regisztrálható. A SwiftUI a legközelebbi megfelelő destination-t keresi navigációs kísérletkor. Ez lehetővé teszi a destination felülírását egy típushoz az alkalmazás különböző részeiben.
1. minta: navigáció enum Route-on keresztül. Definiáljon egy enum-ot kapcsolódó értékekkel az alkalmazás összes képernyőjéhez. Használjon egy .navigationDestination-t az AppRoute-hoz és switch-t az útválasztáshoz. Ez egyetlen igazságforrást biztosít az alkalmazás összes lehetséges átmenetéhez.
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)
}
2. minta: programozott navigáció és deep linking. A NavigationStack lehetővé teszi a verem programozott kezelését: képernyők hozzáadása, eltávolítása és visszatérés a gyökérbe. Ez szükséges push értesítésekhez, mély linkekhez és a navigáció visszaállításához újraindítás után.
3. minta: típusok tömbje a NavigationPath helyett. Ha az összes képernyő egy típust használ (pl. String vagy egyedi enum), használjon Binding-et [T]-hez. Ez szigorúbb típusosztályozást és jobb teljesítményt biztosít, mint a NavigationPath. A NavigationPath heterogén vermekhez indokolt, különböző képernyőtípusokkal.
A Point-Free (2024) szerint a NavigationStack enum Route-tal a preferált módszer a navigáció szervezésére SwiftUI alkalmazásokban. Az összes lehetséges átmenetet explicité, típusbiztossá és tesztelhetővé teszi, ami különösen fontos nagy projektek esetén tucatnyi képernyővel.
Gyakran ismételt kérdések
NavigationStack — egy SwiftUI navigációs konténer (iOS 16+), amely típusbiztos útvonalon keresztül kezeli a képernyők vermét. Lecserélte a NavigationView-t, támogatva a deep linkinget, a programozott navigációt és az állapotmentést.
A NavigationStack típusbiztos útvonalat (NavigationPath) használ a NavigationLink és destination közvetlen összekapcsolása helyett. Támogatja a programozott navigációt, a deep linkinget és a Codable-t az állapotmentéshez. SwiftUI-n dolgozik, nem a UINavigationController-en keresztül.
NavigationPath egy típus, ami a képernyők sorrendjét képviseli a veremben. Értékeket adhat hozzá az útvonalhoz a path.append() vagy a NavigationLink value-val történő használatával. Minden típus megjelenítéséhez .navigationDestination kerül regisztrálásra. A NavigationPath támogatja a Codable-t és az automatikus állapotmentést.
Programozott útvonal-kezeléssel: az URL feldolgozása után hívja meg a path.append()-et a megfelelő útvonalértékkel. A NavigationStack automatikusan megjeleníti a célképernyőt. Visszatérés a győkérbe — path.removeLast(path.count).
Igen, ha a minimális verzió iOS 16+. A NavigationView elavult az iOS 17-ben. Az áttérés típusbiztos navigációt, deep linking támogatást és jobb összehangolást biztosít a SwiftUI életciklussal. iOS 15 és alacsonyabb verziójú projektekhez továbbra is használja a NavigationView-t.
Összegzés
Kulcsrakész mobilalkalmazást fejlesztünk
Az IT Sectr 2017 óta készít iOS és Android alkalmazásokat induló vállalkozásoknak és vállalkozásoknak. Tanácsot adunk, és a legjobb megoldást javasoljuk.
Olvassa el is