NavigationStack: nó là gì, ngăn xếp điều hướng trong SwiftUI

Tác giả: IT Sectr Đã đăng: 2026-06-24 Thời gian đọc: 6 phút

NavigationStack là một container điều hướng hiện đại trong SwiftUI, được giới thiệu trong iOS 16+ và thay thế NavigationView. Theo Tài liệu dành cho nhà phát triển Apple, 2024, NavigationStack quản lý một ngăn xếp màn hình thông qua đường dẫn điều hướng an toàn kiểu (NavigationPath), hỗ trợ điều hướng sâu, quay lại màn hình gốc theo chương trình và bảo toàn trạng thái khi dữ liệu thay đổi. Không giống như NavigationView, NavigationStack không yêu cầu bọc trong một container bổ sung và cung cấp Binding trực tiếp đến đường dẫn điều hướng.

Các điểm chính

  • NavigationStack — container điều hướng SwiftUI mới (iOS 16+)
  • NavigationPath — đường dẫn an toàn kiểu để quản lý ngăn xếp màn hình
  • Deep linking — hỗ trợ điều hướng theo chương trình qua đường dẫn
  • NavigationDestination — đăng ký màn hình đích theo kiểu dữ liệu
  • Trạng thái điều hướng được bảo toàn và khôi phục tự động

NavigationStack trong SwiftUI là gì?

NavigationStack là một View container thực hiện điều hướng dựa trên ngăn xếp (LIFO). Nó quản lý lịch sử chuyển tiếp, cho phép bạn đẩy màn hình mới lên ngăn xếp và quay lại thông qua nút “Quay lại” của hệ thống hoặc theo chương trình. NavigationStack là một phần của SwiftUI từ iOS 16, iPadOS 16, macOS 13, watchOS 9 và tvOS 16.

Cải tiến chính của NavigationStack là đường dẫn điều hướng an toàn kiểu. Thay vì chỉ định trực tiếp đích đến khi tạo NavigationLink, bạn đặt một giá trị vào đường dẫn và View đích được đăng ký riêng thông qua bộ sửa đổi .navigationDestination(for:destination:). Điều này tách biệt điều hướng khỏi kết xuất, làm cho mã trở nên mô-đun hơn và có thể kiểm thử được.

Theo WWDC 2022 (Phiên 10054), NavigationStack sử dụng cơ chế điều hướng mới dựa trên ObservableObject và vòng đời SwiftUI. Không giống như NavigationView phụ thuộc vào UINavigationController bên trong, NavigationStack được triển khai hoàn toàn trong SwiftUI, cải thiện khả năng dự đoán và tương thích với vòng đời SwiftUI.

Cấu trúc cơ bản của NavigationStack

NavigationStack chấp nhận một View gốc và một đường dẫn điều hướng tùy chọn (Binding đến NavigationPath hoặc một mảng các giá trị Hashable). Tất cả màn hình con được đẩy lên ngăn xếp qua NavigationLink hoặc thêm giá trị theo chương trình vào đường dẫn.

NavigationView là container điều hướng chính trong SwiftUI trước iOS 16. Nó tự động quản lý UINavigationController bên trong, dẫn đến một số vấn đề: hành vi không thể đoán trước khi dữ liệu thay đổi, phức tạp với điều hướng theo chương trình và thiếu an toàn kiểu.

Đặc điểmNavigationStack (iOS 16+)NavigationView (iOS 13–15)
Loại điều hướngNgăn xếp (LIFO)Ngăn xếp (LIFO)
Đường dẫn điều hướngĐược kiểu (NavigationPath)Không được hỗ trợ
Deep linkingHỗ trợ tích hợpYêu cầu giải pháp
Quay lại theo chương trìnhQua đường dẫn (pop, popToRoot)dismiss, presentationMode
Bên trongSwiftUI gốcUINavigationController
Tương thíchiOS 16+iOS 13+

Lợi thế chính của NavigationStack — điều hướng an toàn kiểu. Bạn định nghĩa đường dẫn như một mảng các kiểu cụ thể (hoặc NavigationPath cho ngăn xếp không đồng nhất) và đăng ký đích đến cho mỗi kiểu. Điều này loại bỏ lỗi không khớp kiểu và làm cho điều hướng có thể dự đoán được.

NavigationView đã bị deprecated trong iOS 17. Apple khuyến nghị di chuyển sang NavigationStack cho tất cả các dự án mới và khi cập nhật phiên bản tối thiểu lên iOS 16.

NavigationPath là một kiểu đại diện cho đường dẫn điều hướng trong NavigationStack. Nó có thể lưu trữ các giá trị không đồng nhất (AnyHashable) hoặc được sử dụng với một kiểu cụ thể thông qua Binding đến một mảng [T: Hashable]. NavigationPath tự động mã hóa và giải mã để bảo toàn trạng thái.

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

Ngăn xếp không đồng nhất: NavigationPath có thể chứa các giá trị thuộc các kiểu khác nhau nếu chúng triển khai Hashable. Ví dụ: màn hình đầu tiên có thể chấp nhận một String (ID), màn hình thứ hai một Int (số), màn hình thứ ba một enum Route tùy chỉnh. Mỗi kiểu đăng ký một .navigationDestination riêng để hiển thị.

Hỗ trợ Codable: NavigationPath triển khai Codable nếu tất cả các giá trị trong đường dẫn cũng là Codable + Hashable. Điều này cho phép lưu và khôi phục trạng thái điều hướng khi khởi động lại ứng dụng hoặc khi chuyển vào nền.

.navigationDestination(for:destination:) — một bộ sửa đổi đăng ký một View đích cho một kiểu dữ liệu cụ thể. Khi NavigationLink đặt một giá trị thuộc kiểu này vào đường dẫn, SwiftUI tự động tìm .navigationDestination tương ứng và tạo màn hình.

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

Quy tắc quan trọng: .navigationDestination phải được áp dụng cho một View nằm bên trong NavigationStack và trước khi NavigationLink đặt một giá trị vào đường dẫn. Nó thường được thêm vào View gốc hoặc một container phần. Nếu không tìm thấy .navigationDestination cho kiểu của giá trị, quá trình chuyển tiếp sẽ không xảy ra.

Theo SwiftUI Engineering (2023), .navigationDestination có thể được đăng ký ở các cấp khác nhau của hệ thống phân cấp. SwiftUI tìm kiếm đích phù hợp nhất trong quá trình điều hướng. Điều này cho phép ghi đè đích cho một kiểu ở các phần khác nhau của ứng dụng.

Mẫu 1: điều hướng qua enum Route. Định nghĩa một enum với các giá trị liên kết cho tất cả các màn hình trong ứng dụng. Sử dụng một .navigationDestination cho AppRoute và một switch để định tuyến. Điều này cung cấp một nguồn sự thật duy nhất cho tất cả các chuyển tiếp có thể có trong ứng dụng.

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

Mẫu 2: điều hướng theo chương trình và deep linking. NavigationStack cho phép quản lý ngăn xếp theo chương trình: thêm, xóa màn hình và quay lại gốc. Điều này cần thiết cho thông báo push, deep link và khôi phục điều hướng sau khi khởi động lại.

Mẫu 3: mảng các kiểu thay vì NavigationPath. Nếu tất cả các màn hình sử dụng cùng một kiểu (ví dụ: String hoặc enum tùy chỉnh), hãy sử dụng Binding đến [T]. Điều này cung cấp kiểu mạnh hơn và hiệu suất tốt hơn NavigationPath. NavigationPath phù hợp cho các ngăn xếp không đồng nhất với các kiểu màn hình khác nhau.

Theo Point-Free (2024), NavigationStack với enum Route là cách ưa thích để tổ chức điều hướng trong các ứng dụng SwiftUI. Nó làm cho tất cả các chuyển tiếp có thể trở nên rõ ràng, an toàn kiểu và có thể kiểm thử, điều này đặc biệt quan trọng đối với các dự án lớn có hàng chục màn hình.

Các câu hỏi thường gặp

NavigationStack trong SwiftUI là gì?

NavigationStack — một container điều hướng SwiftUI (iOS 16+) quản lý ngăn xếp màn hình thông qua đường dẫn an toàn kiểu. Nó thay thế NavigationView, cung cấp hỗ trợ deep linking, điều hướng theo chương trình và bảo toàn trạng thái.

NavigationStack khác NavigationView như thế nào?

NavigationStack sử dụng đường dẫn an toàn kiểu (NavigationPath) thay vì liên kết trực tiếp NavigationLink với đích đến. Nó hỗ trợ điều hướng theo chương trình, deep linking và Codable để bảo toàn trạng thái. Nó hoạt động trên SwiftUI, không qua UINavigationController.

NavigationPath hoạt động như thế nào?

NavigationPath là một kiểu đại diện cho một chuỗi các màn hình trong ngăn xếp. Bạn thêm giá trị vào đường dẫn qua path.append() hoặc NavigationLink với value. Mỗi kiểu đăng ký một .navigationDestination để hiển thị. NavigationPath hỗ trợ Codable và tự động bảo toàn trạng thái.

Làm thế nào để triển khai deep linking với NavigationStack?

Thông qua quản lý đường dẫn theo chương trình: sau khi xử lý URL, gọi path.append() với giá trị route tương ứng. NavigationStack tự động hiển thị màn hình đích. Quay lại gốc — path.removeLast(path.count).

Có nên di chuyển từ NavigationView sang NavigationStack không?

Có, nếu phiên bản tối thiểu của bạn là iOS 16+. NavigationView đã bị deprecated trong iOS 17. Việc di chuyển mang lại điều hướng an toàn kiểu, hỗ trợ deep linking và căn chỉnh tốt hơn với vòng đời SwiftUI. Đối với các dự án nhắm iOS 15 trở xuống, hãy tiếp tục sử dụng NavigationView cho đến khi có thể nâng cấp.

Tóm tắt

  • NavigationStack — container điều hướng SwiftUI hiện đại (iOS 16+)
  • NavigationPath — đường dẫn an toàn kiểu để quản lý ngăn xếp màn hình
  • NavigationDestination — đăng ký View đích theo kiểu dữ liệu
  • NavigationView deprecated trong iOS 17, di chuyển được khuyến nghị
  • Deep linking và điều hướng theo chương trình — hỗ trợ tích hợp
  • Enum Route — mẫu ưa thích để tổ chức điều hướng
  • Ngăn xếp không đồng nhất qua NavigationPath với bất kỳ kiểu Hashable nào

Chúng tôi sẽ phát triển ứng dụng di động chìa khóa trao tay

IT Sectr tạo các ứng dụng iOS và Android cho các công ty khởi nghiệp và doanh nghiệp từ năm 2017. Chúng tôi sẽ tư vấn và đề xuất giải pháp tốt nhất cho bạn.

Thảo luận dự án

Đọc thêm