NavigationStack: qué es, pila de navegación en SwiftUI

Autor: IT Sectr Publicado: 2026-06-24 Tiempo de lectura: 6 min

NavigationStack es un contenedor de navegación moderno en SwiftUI, presentado en iOS 16+ y que reemplaza a NavigationView. Según la Documentación para desarrolladores de Apple, 2024, NavigationStack gestiona una pila de pantallas a través de una ruta de navegación con seguridad de tipos (NavigationPath), admite navegación profunda, retorno programático a la pantalla raíz y conservación del estado al cambiar los datos. A diferencia de NavigationView, NavigationStack no requiere envoltura en un contenedor adicional y proporciona un Binding directo a la ruta de navegación.

Puntos clave

  • NavigationStack — nuevo contenedor de navegación SwiftUI (iOS 16+)
  • NavigationPath — ruta con seguridad de tipos para gestionar la pila de pantallas
  • Deep linking — soporte para navegación programática mediante ruta
  • NavigationDestination — registro de pantallas de destino por tipos de datos
  • Estado de navegación se conserva y restaura automáticamente

¿Qué es NavigationStack en SwiftUI?

NavigationStack es una Vista contenedora que implementa navegación basada en pila (LIFO). Gestiona el historial de transiciones, permitiendo colocar nuevas pantallas en la pila y volver atrás mediante el botón “Atrás” del sistema o de forma programática. NavigationStack forma parte de SwiftUI desde iOS 16, iPadOS 16, macOS 13, watchOS 9 y tvOS 16.

La principal innovación de NavigationStack es la ruta de navegación con seguridad de tipos. En lugar de especificar directamente un destino al crear un NavigationLink, se coloca un valor en la ruta, y la Vista de destino se registra por separado mediante el modificador .navigationDestination(for:destination:). Esto separa la navegación de la representación, haciendo el código más modular y comprobable.

Según WWDC 2022 (Sesión 10054), NavigationStack utiliza un nuevo mecanismo de navegación basado en ObservableObject y el ciclo de vida de SwiftUI. A diferencia de NavigationView, que dependía de UINavigationController internamente, NavigationStack está completamente implementado en SwiftUI, mejorando la previsibilidad y la compatibilidad con el ciclo de vida de SwiftUI.

Estructura básica de NavigationStack

NavigationStack acepta una Vista raíz y una ruta de navegación opcional (Binding a NavigationPath o un array de valores Hashable). Todas las pantallas hijas se colocan en la pila mediante NavigationLink o añadiendo valores programáticamente a la ruta.

NavigationView fue el contenedor de navegación principal en SwiftUI antes de iOS 16. Gestionaba automáticamente UINavigationController internamente, lo que provocaba varios problemas: comportamiento impredecible al cambiar datos, complejidad con la navegación programática y falta de seguridad de tipos.

CaracterísticaNavigationStack (iOS 16+)NavigationView (iOS 13–15)
Tipo de navegaciónPila (LIFO)Pila (LIFO)
Ruta de navegaciónTipada (NavigationPath)No soportada
Deep linkingSoporte integradoRequiere soluciones
Retorno programáticoMediante ruta (pop, popToRoot)dismiss, presentationMode
InternamenteSwiftUI nativoUINavigationController
CompatibilidadiOS 16+iOS 13+

Ventaja clave de NavigationStack — navegación con seguridad de tipos. Se define la ruta como un array de tipos específicos (o NavigationPath para pilas heterogéneas) y se registra un destino para cada tipo. Esto elimina errores de discrepancia de tipos y hace la navegación predecible.

NavigationView está obsoleto en iOS 17. Apple recomienda migrar a NavigationStack para todos los proyectos nuevos y al actualizar la versión mínima a iOS 16.

NavigationPath es un tipo que representa la ruta de navegación en NavigationStack. Puede almacenar valores heterogéneos (AnyHashable) o usarse con un tipo específico mediante Binding a un array [T: Hashable]. NavigationPath se codifica y decodifica automáticamente para conservar el estado.

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

Pila heterogénea: NavigationPath puede contener valores de diferentes tipos si implementan Hashable. Por ejemplo, la primera pantalla puede aceptar un String (ID), la segunda un Int (número), la tercera un enum Route personalizado. Cada tipo registra un .navigationDestination separado para su visualización.

Soporte Codable: NavigationPath implementa Codable si todos los valores en la ruta también son Codable + Hashable. Esto permite guardar y restaurar el estado de navegación al reiniciar la aplicación o al entrar en segundo plano.

.navigationDestination(for:destination:) — un modificador que registra una Vista de destino para un tipo de datos específico. Cuando NavigationLink coloca un valor de este tipo en la ruta, SwiftUI encuentra automáticamente el .navigationDestination correspondiente y crea la pantalla.

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

Regla importante: .navigationDestination debe aplicarse a una Vista que esté dentro de NavigationStack, y antes de que NavigationLink coloque un valor en la ruta. Generalmente se añade a la Vista raíz o a un contenedor de sección. Si no se encuentra .navigationDestination para el tipo del valor, la transición no se producirá.

Según SwiftUI Engineering (2023), .navigationDestination puede registrarse en diferentes niveles de la jerarquía. SwiftUI busca el destino más cercano durante la navegación. Esto permite sobrescribir el destino para un tipo en diferentes partes de la aplicación.

Patrón 1: navegación mediante enum Route. Defina un enum con valores asociados para todas las pantallas de la aplicación. Use un .navigationDestination para AppRoute y un switch para el enrutamiento. Esto proporciona una única fuente de verdad para todas las transiciones posibles en la aplicación.

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

Patrón 2: navegación programática y deep linking. NavigationStack permite la gestión programática de la pila: añadir, eliminar pantallas y volver a la raíz. Esto es necesario para notificaciones push, deep links y restauración de la navegación tras un reinicio.

Patrón 3: array de tipos en lugar de NavigationPath. Si todas las pantallas usan el mismo tipo (por ejemplo, String o un enum personalizado), use Binding a [T]. Esto proporciona una tipificación más estricta y mejor rendimiento que NavigationPath. NavigationPath está justificado para pilas heterogéneas con diferentes tipos de pantallas.

Según Point-Free (2024), NavigationStack con enum Route es la forma preferida de organizar la navegación en aplicaciones SwiftUI. Hace que todas las transiciones posibles sean explícitas, seguras en cuanto a tipos y comprobables, lo que es especialmente importante para proyectos grandes con decenas de pantallas.

Preguntas frecuentes

¿Qué es NavigationStack en SwiftUI?

NavigationStack — un contenedor de navegación SwiftUI (iOS 16+) que gestiona una pila de pantallas mediante una ruta con seguridad de tipos. Reemplazó a NavigationView, ofreciendo soporte para deep linking, navegación programática y conservación del estado.

¿En qué se diferencia NavigationStack de NavigationView?

NavigationStack utiliza una ruta con seguridad de tipos (NavigationPath) en lugar de enlazar directamente NavigationLink a un destino. Admite navegación programática, deep linking y Codable para la conservación del estado. Funciona en SwiftUI, no a través de UINavigationController.

¿Cómo funciona NavigationPath?

NavigationPath es un tipo que representa una secuencia de pantallas en la pila. Se añaden valores a la ruta mediante path.append() o NavigationLink con value. Cada tipo registra un .navigationDestination para su visualización. NavigationPath admite Codable y la conservación automática del estado.

¿Cómo implementar deep linking con NavigationStack?

Mediante la gestión programática de la ruta: tras procesar la URL, llame a path.append() con el valor de ruta correspondiente. NavigationStack muestra automáticamente la pantalla de destino. Volver a la raíz — path.removeLast(path.count).

¿Debo migrar de NavigationView a NavigationStack?

Sí, si su versión mínima es iOS 16+. NavigationView está obsoleto en iOS 17. La migración proporciona navegación con seguridad de tipos, soporte de deep linking y una mejor alineación con el ciclo de vida de SwiftUI. Para proyectos con iOS 15 y versiones inferiores, siga usando NavigationView por ahora.

Resumen

  • NavigationStack — contenedor de navegación SwiftUI moderno (iOS 16+)
  • NavigationPath — ruta con seguridad de tipos para gestionar la pila de pantallas
  • NavigationDestination — registro de Vistas de destino por tipos de datos
  • NavigationView obsoleto en iOS 17, migración recomendada
  • Deep linking y navegación programática — soporte integrado
  • Enum Route — patrón preferido para organizar la navegación
  • Pila heterogénea mediante NavigationPath con cualquier tipo Hashable

Desarrollaremos una aplicación móvil llave en mano

IT Sectr crea aplicaciones para iOS y Android para startups y empresas desde 2017. Le asesoraremos y le propondremos la mejor solución.

Discutir el proyecto

Lea también