NavigationView es un componente contenedor de SwiftUI para organizar la navegación en pila entre pantallas. NavigationView crea una pila de navegación con una barra de navegación automática, título y botón «Atrás». Desde iOS 16, Apple recomienda usar NavigationStack. Lea más en documentación de Apple.
Puntos clave
NavigationView es un contenedor SwiftUI que envuelve una jerarquía de pantallas y proporciona una interfaz de navegación. Dentro de NavigationView funciona NavigationLink — un elemento que al pulsarlo reemplaza la pantalla actual por una nueva. NavigationView añade automáticamente una barra de navegación con título y botón «Atrás».
NavigationView apareció en iOS 13 junto con SwiftUI. Conceptualmente reemplaza UINavigationController de UIKit, pero está implementado de forma declarativa. En lugar de push/pop manual, el desarrollador describe la relación entre pantallas mediante NavigationLink. El sistema gestiona la pila automáticamente.
NavigationView soporta los modificadores .navigationTitle, .navigationBarTitleDisplayMode, .toolbar y .searchable. Para iOS 16+, Apple introdujo NavigationStack, que conserva la API de NavigationView pero añade gestión programática de la pila mediante NavigationPath. Para proyectos con soporte hasta iOS 15, NavigationView sigue siendo la única opción.
NavigationLink es un elemento SwiftUI que crea una transición a una pantalla de destino dentro de NavigationView o NavigationStack. Al pulsar NavigationLink, el sistema añade la pantalla de destino a la pila de navegación. La animación de transición es el push estándar desde la derecha en iOS, adaptándose a la plataforma.
struct ContentView: View {
var body: some View {
NavigationView {
List(items) { item in
NavigationLink(destination: DetailView(item: item)) {
Text(item.title)
}
}
.navigationTitle("Lista")
}
}
}
struct DetailView: View {
let item: Item
var body: some View {
VStack {
Text(item.description)
.navigationTitle(item.title)
.navigationBarTitleDisplayMode(.inline)
}
}
}NavigationLink acepta dos parámetros: destination — la View de destino, y label — el elemento que pulsa el usuario. Para listas, es conveniente la sintaxis con value y NavigationLink(value:), que deselecciona la celda automáticamente y funciona con NavigationPath.
Con iOS 16, Apple presentó NavigationStack como reemplazo de NavigationView. NavigationStack conserva la sintaxis declarativa pero añade una característica críticamente importante — la gestión programática de la pila mediante la propiedad path de tipo NavigationPath o un array de Hashable.
| Característica | NavigationView (iOS 13-15) | NavigationStack (iOS 16+) |
|---|---|---|
| Push programático | No, solo mediante NavigationLink | Sí, mediante path.append(value) |
| popToRoot | Solo dismiss hasta root | path.removeLast(path.count) |
| Deep Links | Implementación compleja | Soporte integrado mediante path |
| Tipado de pila | No (cualquier View en destination) | Sí (array de valores Hashable) |
| SplitView iPad | ColumnStyle / StackStyle | NavigationSplitView (iOS 16+) |
Para proyectos con versión mínima iOS 16+, use NavigationStack. Para soporte iOS 14-15 — NavigationView. NavigationStack no tiene análogos directos para versiones antiguas, por lo que la actualización requiere verificar la compatibilidad.
Los modificadores .toolbar y .navigationTitle controlan el contenido de la barra de navegación. .navigationTitle establece el título de la pantalla, .navigationBarTitleDisplayMode selecciona el estilo: .large (grande, por defecto) o .inline (compacto, como en Ajustes). .toolbar añade botones, búsqueda y control segmentado.
struct SettingsView: View {
var body: some View {
NavigationStack {
Form {
Section("Perfil") {
Text("Nombre de usuario")
Toggle("Notificaciones", isOn: $notifications)
}
}
.navigationTitle("Ajustes")
.navigationBarTitleDisplayMode(.large)
.toolbar {
ToolbarItem(placement: .navigationBarTrailing) {
Button("Guardar") { save() }
}
ToolbarItem(placement: .navigationBarLeading) {
EditButton()
}
}
}
}
}.searchable es otro modificador que integra una barra de búsqueda en la barra de navegación. Funciona tanto con NavigationView como con NavigationStack. La búsqueda se oculta automáticamente al hacer scroll y se muestra al deslizar hacia abajo. Soporta filtrado de listas mediante un Binding String.
NavigationPath es un tipo de iOS 16+ que representa una pila de navegación como una colección de valores Hashable. El desarrollador añade elementos al path para la transición programática y los elimina para volver atrás. NavigationPath soporta deep links, notificaciones push y restauración del estado.
struct AppNavigation: View {
@State private var path = NavigationPath()
var body: some View {
NavigationStack(path: $path) {
List(categories) { category in
NavigationLink("Categoría \(category.name)",
value: category)
}
.navigationTitle("Categorías")
.navigationDestination(for: Category.self) { category in
ProductListView(category: category)
}
.navigationDestination(for: Product.self) { product in
ProductDetailView(product: product)
}
}
// Navegación programática por deep link
.onOpenURL { url in
guard let productId = DeepLinkParser.parse(url) else { return }
path.append(Product(id: productId))
}
}
}.navigationDestination(for:) registra un tipo de dato para el que mostrar una pantalla. Cuando se añade un valor de este tipo al path, el sistema crea automáticamente la View de destino. Este enfoque reemplaza el NavigationLink(destination:) explícito y hace que la navegación sea estrictamente tipada.
NavigationView y NavigationStack funcionan en todas las plataformas Apple: iOS, iPadOS, watchOS, tvOS y macOS. El comportamiento se adapta a la pantalla. En iPad, NavigationStack soporta NavigationSplitView, que reemplaza UISplitViewController de UIKit y muestra dos columnas en pantalla ancha.
NavigationSplitView (iOS 16+) divide la pantalla en sidebar (lista) y detalle. En iPhone, el sidebar se oculta mostrando solo el detalle mediante NavigationLink. En iPad, sidebar y detalle se muestran simultáneamente en modo split.
struct AdaptiveNavigation: View {
@State private var selectedCategory: Category?
var body: some View {
NavigationSplitView {
List(categories, selection: $selectedCategory) { category in
Text(category.name)
}
.navigationTitle("Categorías")
} detail: {
ProductListView(category: selectedCategory)
}
}
}NavigationSplitView selecciona automáticamente el modo de visualización óptimo para cada dispositivo. En iPhone en vertical — pila, en iPad y iPhone en horizontal — split. El desarrollador no necesita escribir código separado para diferentes size classes.
Preguntas frecuentes
NavigationView es la API antigua (iOS 13-15), solo soporta NavigationLink declarativo. NavigationStack es la nueva API (iOS 16+), añade path para navegación programática, deep links y una pila estrictamente tipada. Apple recomienda NavigationStack para proyectos nuevos.
Mediante el modificador .toolbar con ToolbarItem. Por ejemplo: .toolbar { ToolbarItem(placement: .navigationBarTrailing) { Button('Ajustes') { } } }. Placement determina la posición: trailing (derecha), leading (izquierda), principal (centro).
El título se establece mediante .navigationTitle('Título'). Estilo — .navigationBarTitleDisplayMode(.large) o .inline. Large — título grande al estilo iOS Music, inline — compacto, como en Ajustes. El estilo se puede cambiar para cada pantalla individualmente.
Tres formas: mediante value (NavigationLink(value:item) { Label }, iOS 16+), mediante destination + label, mediante isActive para transición programática. NavigationLink con value es más limpio para listas ya que no requiere crear la View de destino antes de la transición.
Sí. NavigationView y NavigationStack están disponibles en iOS, iPadOS, watchOS, tvOS y macOS. En watchOS la navegación usa la jerarquía de interfaz con la Digital Crown, en tvOS — entrada basada en foco con el mando. El comportamiento se adapta a la plataforma automáticamente.
Resumen
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.
Lea también