NavigationStack: o que é, pilha de navegação em SwiftUI

Autor: IT Sectr Publicado: 2026-06-24 Tempo de leitura: 6 min

NavigationStack é um contêiner de navegação moderno em SwiftUI, apresentado no iOS 16+ e substituindo o NavigationView. De acordo com a Documentação do Desenvolvedor Apple, 2024, o NavigationStack gerencia uma pilha de telas através de um caminho de navegação type-safe (NavigationPath), suporta navegação profunda, retorno programático à tela raiz e preservação de estado quando os dados mudam. Ao contrário do NavigationView, o NavigationStack não requer encapsulamento em um contêiner adicional e fornece um Binding direto ao caminho de navegação.

Pontos principais

  • NavigationStack — novo contêiner de navegação SwiftUI (iOS 16+)
  • NavigationPath — caminho type-safe para gerenciar a pilha de telas
  • Deep linking — suporte para navegação programática via caminho
  • NavigationDestination — registro de telas de destino por tipos de dados
  • Estado de navegação é preservado e restaurado automaticamente

O que é NavigationStack em SwiftUI?

NavigationStack é uma View contêiner que implementa navegação baseada em pilha (LIFO). Ela gerencia o histórico de transições, permitindo colocar novas telas na pilha e voltar através do botão “Voltar” do sistema ou programaticamente. NavigationStack faz parte do SwiftUI a partir do iOS 16, iPadOS 16, macOS 13, watchOS 9 e tvOS 16.

A principal inovação do NavigationStack é o caminho de navegação type-safe. Em vez de especificar diretamente um destino ao criar um NavigationLink, você coloca um valor no caminho, e a View de destino é registrada separadamente através do modificador .navigationDestination(for:destination:). Isso separa a navegação da renderização, tornando o código mais modular e testável.

De acordo com a WWDC 2022 (Sessão 10054), o NavigationStack usa um novo mecanismo de navegação baseado em ObservableObject e no ciclo de vida do SwiftUI. Ao contrário do NavigationView, que dependia do UINavigationController internamente, o NavigationStack é totalmente implementado em SwiftUI, melhorando a previsibilidade e a compatibilidade com o ciclo de vida do SwiftUI.

Estrutura básica do NavigationStack

NavigationStack aceita uma View raiz e um caminho de navegação opcional (Binding para NavigationPath ou um array de valores Hashable). Todas as telas filhas são colocadas na pilha através de NavigationLink ou adicionando valores programaticamente ao caminho.

NavigationView era o principal contêiner de navegação em SwiftUI antes do iOS 16. Ele gerenciava automaticamente o UINavigationController internamente, o que levava a vários problemas: comportamento imprevisível ao alterar dados, complexidade com navegação programática e falta de type safety.

CaracterísticaNavigationStack (iOS 16+)NavigationView (iOS 13–15)
Tipo de navegaçãoPilha (LIFO)Pilha (LIFO)
Caminho de navegaçãoTipado (NavigationPath)Não suportado
Deep linkingSuporte integradoRequer soluções
Retorno programáticoVia caminho (pop, popToRoot)dismiss, presentationMode
InternamenteSwiftUI nativoUINavigationController
CompatibilidadeiOS 16+iOS 13+

Vantagem principal do NavigationStack — navegação type-safe. Você define o caminho como um array de tipos específicos (ou NavigationPath para pilhas heterogêneas) e registra um destino para cada tipo. Isso elimina erros de incompatibilidade de tipos e torna a navegação previsível.

NavigationView está obsoleto no iOS 17. A Apple recomenda migrar para NavigationStack em todos os novos projetos e ao atualizar a versão mínima para iOS 16.

NavigationPath é um tipo que representa o caminho de navegação no NavigationStack. Ele pode armazenar valores heterogêneos (AnyHashable) ou ser usado com um tipo específico via Binding a um array [T: Hashable]. NavigationPath codifica e decodifica automaticamente para preservação de 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")
    }
}

Pilha heterogênea: NavigationPath pode conter valores de diferentes tipos se eles implementarem Hashable. Por exemplo, a primeira tela pode aceitar uma String (ID), a segunda um Int (número), a terceira um enum Route personalizado. Cada tipo registra um .navigationDestination separado para exibição.

Suporte Codable: NavigationPath implementa Codable se todos os valores no caminho também forem Codable + Hashable. Isso permite salvar e restaurar o estado de navegação ao reiniciar o aplicativo ou ao entrar em segundo plano.

.navigationDestination(for:destination:) — um modificador que registra uma View de destino para um tipo de dados específico. Quando NavigationLink coloca um valor desse tipo no caminho, SwiftUI encontra automaticamente o .navigationDestination correspondente e cria a tela.

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

Regra importante: .navigationDestination deve ser aplicado a uma View que esteja dentro do NavigationStack, e antes que NavigationLink coloque um valor no caminho. Geralmente é adicionado à View raiz ou a um contêiner de seção. Se nenhum .navigationDestination for encontrado para o tipo do valor, a transição não ocorrerá.

De acordo com a SwiftUI Engineering (2023), .navigationDestination pode ser registrado em diferentes níveis da hierarquia. SwiftUI procura o destino mais próximo durante a navegação. Isso permite substituir o destino para um tipo em diferentes partes do aplicativo.

Padrão 1: navegação via enum Route. Defina um enum com valores associados para todas as telas do aplicativo. Use um .navigationDestination para AppRoute e um switch para roteamento. Isso fornece uma única fonte de verdade para todas as transições possíveis no aplicativo.

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

Padrão 2: navegação programática e deep linking. NavigationStack permite gerenciamento programático da pilha: adicionar, remover telas e retornar à raiz. Isso é necessário para notificações push, deep links e restauração da navegação após reinicialização.

Padrão 3: array de tipos em vez de NavigationPath. Se todas as telas usam o mesmo tipo (por exemplo, String ou um enum personalizado), use Binding para [T]. Isso fornece tipagem mais forte e melhor desempenho que NavigationPath. NavigationPath é justificado para pilhas heterogêneas com diferentes tipos de tela.

De acordo com a Point-Free (2024), NavigationStack com enum Route é a maneira preferida de organizar a navegação em aplicativos SwiftUI. Torna todas as transições possíveis explícitas, type-safe e testáveis, o que é especialmente importante para grandes projetos com dezenas de telas.

Perguntas frequentes

O que é NavigationStack em SwiftUI?

NavigationStack — um contêiner de navegação SwiftUI (iOS 16+) que gerencia uma pilha de telas através de um caminho type-safe. Substituiu o NavigationView, oferecendo suporte a deep linking, navegação programática e preservação de estado.

Como o NavigationStack difere do NavigationView?

NavigationStack usa um caminho type-safe (NavigationPath) em vez de vincular diretamente NavigationLink a um destino. Suporta navegação programática, deep linking e Codable para preservação de estado. Funciona em SwiftUI, não através de UINavigationController.

Como funciona o NavigationPath?

NavigationPath é um tipo que representa uma sequência de telas na pilha. Você adiciona valores ao caminho via path.append() ou NavigationLink com value. Cada tipo registra um .navigationDestination para exibição. NavigationPath suporta Codable e preservação automática de estado.

Como implementar deep linking com NavigationStack?

Através do gerenciamento programático do caminho: após processar a URL, chame path.append() com o valor de rota correspondente. NavigationStack exibe automaticamente a tela de destino. Retorno à raiz — path.removeLast(path.count).

Devo migrar de NavigationView para NavigationStack?

Sim, se sua versão mínima for iOS 16+. NavigationView está obsoleto no iOS 17. A migração fornece navegação type-safe, suporte a deep linking e melhor alinhamento com o ciclo de vida do SwiftUI. Para projetos com iOS 15 e inferior, continue usando NavigationView por enquanto.

Resumo

  • NavigationStack — contêiner de navegação SwiftUI moderno (iOS 16+)
  • NavigationPath — caminho type-safe para gerenciar pilha de telas
  • NavigationDestination — registro de Views de destino por tipos de dados
  • NavigationView obsoleto no iOS 17, migração recomendada
  • Deep linking e navegação programática — suporte integrado
  • Enum Route — padrão preferido para organizar navegação
  • Pilha heterogênea via NavigationPath com qualquer tipo Hashable

Vamos desenvolver um aplicativo móvel chave na mão

A IT Sectr cria aplicativos para iOS e Android para startups e empresas desde 2017. Nós vamos aconselhá-lo e propor a melhor solução.

Discutir o projeto

Leia também