NavigationStack: τι είναι, στοίβα πλοήγησης στο SwiftUI

Συγγραφέας: IT Sectr Δημοσιεύτηκε: 2026-06-24 Χρόνος ανάγνωσης: 6 λεπ

Ο NavigationStack είναι ένα σύγχρονο κοντεινές πλοήγησης στο SwiftUI, που εισήχθηκε στο iOS 16+ και αντικατέστησε το NavigationView. Σύμφωνα με Apple Developer Documentation, 2024, το NavigationStack διαχειρίζεται τη στοίβα οθονών μέσω μιας ασφαλούς από πλευράς τύπων διαδρομής πλοήγησης (NavigationPath), υποστηρίζει βαθεία πλοήγηση, προγραμματική επιστροφή στην αρχική οθόνη και διατήρηση κατάστασης κατά την αλλαγή δεδομένων. Σε αντίθεση με το NavigationView, το NavigationStack δεν απαιτεί περιτύλιξη σε επιπλέον κοντεινές και παρέχει άμεσο Binding στη διαδρομή πλοήγησης.

Κύρια

  • NavigationStack — νέο κοντεινές πλοήγησης SwiftUI (iOS 16+)
  • NavigationPath — ασφαλής από πλευράς τύπων διαδρομή για διαχείριση στοίβας οθονών
  • Deep linking — υποστήριξη προγραμματικής πλοήγησης μέσω διαδρομής
  • NavigationDestination — καταχώρηση οθονών προορισμού βάσει τύπων δεδομένων
  • Κατάσταση πλοήγησης αποθηκεύεται και αποκαθίσταται αυτόματα

Τι είναι το NavigationStack στο SwiftUI;

NavigationStack είναι ένα κοντεινές View που υλοποιεί πλοήγηση βασισμένη σε στοίβα (LIFO). Διαχειρίζεται το ιστορικό μεταβάσεων, επιτρέποντας την τοποθέτηση νέων οθονών στη στοίβα και την επιστροφή μέσω του κουμπιού συστήματος «Πίσω» ή προγραμματικά. Το NavigationStack είναι μέρος του SwiftUI από το iOS 16, iPadOS 16, macOS 13, watchOS 9 και tvOS 16.

Η κύρια καινοτομία του NavigationStack είναι η ασφαλής από πλευράς τύπων διαδρομή πλοήγησης. Αντί να καθορίζετε άμεσα destination κατά τη δημιουργία NavigationLink, τοποθετείτε μια τιμή (value) στη διαδρομή, και η καταχώρηση του προορισμού View γίνεται ξεχωριστά μέσω του τροποποιητή .navigationDestination(for:destination:). Αυτό διαχωρίζει την πλοήγηση και την εμφάνιση, καθιστώντας τον κώδικα πιο αρθρωματικό και δοκιμάσιμο.

Σύμφωνα με το WWDC 2022 (Session 10054), το NavigationStack χρησιμοποιεί έναν νέο μηχανισμό πλοήγησης βασισμένο σε ObservableObject και στον κύκλο ζωής του SwiftUI. Σε αντίθεση με το NavigationView που βασιζόταν σε UINavigationController κάτω από την καπότα, το NavigationStack είναι πλήρως υλοποιημένο στο SwiftUI, βελτιώνοντας την προβλεψιμότητα και τη συμβατότητα με τον κύκλο ζωής του SwiftUI.

Βασική δομή του NavigationStack

Το NavigationStack δέχεται ένα ριζικό View και μια προαιρετική διαδρομή πλοήγησης (Binding σε NavigationPath ή σε πίνακα τιμών Hashable). Όλες οι θυγατρικές οθόνες τοποθετούνται στη στοίβα μέσω NavigationLink ή προγραμματικής προσθήκης τιμών στη διαδρομή.

NavigationView ήταν ο κύριος κοντεινές πλοήγησης του SwiftUI μέχρι το iOS 16. Διαχειριζόταν αυτόματα το UINavigationController κάτω από την καπότα, κάτι που οδηγούσε σε μια σειρά προβλημάτων: απρόβλεπτη συμπεριφορά κατά την αλλαγή δεδομένων, δυσκολίες με την προγραμματική πλοήγηση και έλλειψη ασφάλειας τύπων.

ΧαρακτηριστικόNavigationStack (iOS 16+)NavigationView (iOS 13–15)
Τύπος πλοήγησηςΣτοίβα (LIFO)Στοίβα (LIFO)
Διαδρομή πλοήγησηςΤυποποιημένη (NavigationPath)Δεν υποστηρίζεται
Deep linkingΕνσωματωμένη υποστήριξηΑπαιτεί hacks
Προγραμματική επιστροφήΜέσω διαδρομής (pop, popToRoot)dismiss, presentationMode
Κάτω από την καπόταSwiftUI nativeUINavigationController
ΣυμβατότηταiOS 16+iOS 13+

Βασικό πλεονέκτημα του NavigationStack — ασφαλής από πλευράς τύπων πλοήγηση. Καθορίζετε τη διαδρομή ως πίνακα συγκεκριμένων τύπων (ή NavigationPath για ετερογενείς στοίβες) και καταχωρίζετε destination για κάθε τύπο. Αυτό εξαλείφει τα σφάλματα ασυμβατότητας τύπων και καθιστά την πλοήγηση προβλέψιμη.

Το NavigationView είναι απαραίτητο στο iOS 17. Η Apple συνιστά τη μετανάστευση σε NavigationStack για όλα τα νέα έργα και κατά την ενημέρωση της ελάχιστης έκδοσης σε iOS 16.

NavigationPath είναι ένας τύπος που αντιπροσωπεύει τη διαδρομή πλοήγησης στο NavigationStack. Μπορεί να αποθηκεύει ετερογενείς τιμές (AnyHashable) ή να χρησιμοποιηθεί με συγκεκριμένο τύπο μέσω Binding σε πίνακα [T: Hashable]. Το NavigationPath κωδικοποιείται και αποκωδικοποιείται αυτόματα για τη διατήρηση της κατάστασης.

swift
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")
    }
}

Ετερογενής στοίβα: Το NavigationPath μπορεί να περιέχει τιμές διαφορετικών τύπων, εάν υλοποιούν το Hashable. Για παράδειγμα, η πρώτη οθόνη μπορεί να δέχεται String (ID), η δεύτερη — Int (αριθμό), η τρίτη — ένα προσαρμοσμένο enum Route. Για την εμφάνιση κάθε τύπου καταχωρίζεται ξεχωριστό .navigationDestination.

Υποστήριξη Codable: Το NavigationPath υλοποιεί το Codable, εάν όλες οι τιμές στη διαδρομή είναι επίσης Codable + Hashable. Αυτό επιτρέπει την αποθήκευση και επαναφορά της κατάστασης πλοήγησης κατά την επανεκκίνηση της εφαρμογής ή κατά τη μετάβαση σε λειτουργία υποβάθρου.

.navigationDestination(for:destination:) — ένας τροποποιητής που καταχωρίζει το View προορισμού για έναν συγγεκριμένο τύπο δεδομένων. Όταν το NavigationLink τοποθετεί μια τιμή αυτού του τύπου στη διαδρομή, το SwiftUI βρίσκει αυτόματα το αντίστοιχο .navigationDestination και δημιουργεί την οθόνη.

swift
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"))

Σημαντικός κανόνας: Το .navigationDestination πρέπει να εφαρμόζεται σε ένα View που βρίσκεται μέσα στο NavigationStack, και πριν το NavigationLink τοποθετήσει μια τιμή στη διαδρομή. Συνήθως προστίθεται στο ριζικό View ή στο κοντεινές τομής. Εάν δεν βρεθεί .navigationDestination για τον τύπο της τιμής, η μετάβαση δεν πραγματοποιείται.

Σύμφωνα με το SwiftUI Engineering (2023), το .navigationDestination μπορεί να καταχωριστεί σε διαφορετικά επίπεδα της ιεραρχίας. Το SwiftUI αναζητά το κοντύτερο κατάλληλο destination κατά την προσπάθεια πλοήγησης. Αυτό επιτρέπει την παρακαμπή του destination για ένα τύπο σε διαφορετικά μέρη της εφαρμογής.

Πρότυπο 1: πλοήγηση μέσω enum Route. Ορίστε ένα enum με συνδεδεμένες τιμές για όλες τις οθόνες της εφαρμογής. Χρησιμοποιήστε ένα .navigationDestination για το AppRoute και switch για διαδρομολόγηση. Αυτό παρέχει μια ενιαία πηγή αλήθειας για όλες τις δυνατές μεταβάσεις στην εφαρμογή.

swift
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: προγραμματική πλοήγηση και deep linking. Το NavigationStack επιτρέπει την προγραμματική διαχείριση της στοίβας: προσθήκη, αφαίρεση οθονών και επιστροφή στη ρίζα. Αυτό είναι απαραίτητο για ειδοποιήσεις push, βαθείς συνδέσμους και επαναφορά πλοήγησης μετά από επανεκκίνηση.

Πρότυπο 3: πίνακας τύπων αντί για NavigationPath. Εάν όλες οι οθόνες χρησιμοποιούν ένα τύπο (π.χ. String ή ένα προσαρμοσμένο enum), χρησιμοποιήστε Binding σε [T]. Αυτό παρέχει αυστηρότερη τυποποίηση και καλύτερη απόδοση από το NavigationPath. Το NavigationPath δικαιολογείται για ετερογενείς στοίβες με διαφορετικούς τύπους οθονών.

Σύμφωνα με το Point-Free (2024), το NavigationStack με enum Route είναι ο προτιμώμενος τρόπος οργάνωσης πλοήγησης σε εφαρμογές SwiftUI. Κάθει όλες τις δυνατές μεταβάσεις ρητές, ασφαλείς από πλευράς τύπων και δοκιμάσιμες, κάτι που είναι ιδιαίτερα σημαντικό για μεγάλα έργα με δοσάδες οθόνες.

Συχνές ερωτήσεις

Τι είναι το NavigationStack στο SwiftUI;

NavigationStack — ένας κοντεινές πλοήγησης SwiftUI (iOS 16+) που διαχειρίζεται τη στοίβα οθονών μέσω μιας ασφαλούς διαδρομής. Αντικατέστησε το NavigationView, προσφέροντας υποστήριξη για deep linking, προγραμματική πλοήγηση και αποθήκευση κατάστασης.

Σε τι διαφέρει το NavigationStack από το NavigationView;

Το NavigationStack χρησιμοποιεί μια ασφαλή διαδρομή (NavigationPath) αντί για άμεση σύνδεση του NavigationLink με destination. Υποστηρίζει προγραμματική πλοήγηση, deep linking και Codable για αποθήκευση κατάστασης. Λειτουργεί σε SwiftUI, όχι μέσω UINavigationController.

Πως λειτουργεί το NavigationPath;

NavigationPath είναι ένας τύπος που αντιπροσωπεύει την ακολουθία των οθονών στη στοίβα. Προσθέτετε τιμές στη διαδρομή μέσω path.append() ή μέσω NavigationLink με value. Για εμφάνιση κάθε τύπου καταχωρίζεται .navigationDestination. Το NavigationPath υποστηρίζει Codable και αυτόματη αποθήκευση κατάστασης.

Πως να υλοποιήσω deep linking με NavigationStack;

Μέσω προγραμματικής διαχείρισης διαδρομής: μετά την επεξεργασία URL, καλέστε path.append() με την αντίστοιχη τιμή διαδρομής. Το NavigationStack θα εμφανίσει αυτόματα την οθόνη προορισμού. Επιστροφή στη ρίζα — path.removeLast(path.count).

Πρέπει να μεταναστώ από NavigationView σε NavigationStack;

Ναι, εάν η ελάχιστη έκδοσή σας είναι iOS 16+. Το NavigationView είναι απαραίτητο στο iOS 17. Η μετανάστευση παρέχει ασφαλή πλοήγηση, υποστήριξη deep linking και καλύτερη συμβατότητα με τον κύκλο ζωής του SwiftUI. Για έργα με iOS 15 και χαμηλότερα, χρησιμοποιείτε ακόμη NavigationView.

Περίληψη

  • NavigationStack — σύγχρονος κοντεινές πλοήγησης SwiftUI (iOS 16+)
  • NavigationPath — ασφαλής διαδρομή για διαχείριση στοίβας οθονών
  • NavigationDestination — καταχώρηση View προορισμού βάσει τύπων δεδομένων
  • NavigationView απαραίτητο στο iOS 17, συνιστάται η μετανάστευση
  • Deep linking και προγραμματική πλοήγηση — ενσωματωμένη υποστήριξη
  • Enum Route — προτιμώμενο πρότυπο για οργάνωση πλοήγησης
  • Ετερογενής στοίβα μέσω NavigationPath με οποιονδήποτε Hashable τύπο

Θα αναπτύξουμε μια εφαρμογή για κινητά έτοιμη για χρήση

Η IT Sectr δημιουργεί εφαρμογές iOS και Android για νεοφυείς επιχειρήσεις και επιχειρήσεις από το 2017. Θα σας συμβουλεύσουμε και θα προτείνουμε την καλύτερη λύση.

Συζήτηση έργου

Διαβάστε επίσης