NavigationLink é um elemento de controle no SwiftUI projetado para a transição para outra tela no NavigationStack ou NavigationView. De acordo com Apple Developer Documentation, 2024, NavigationLink cria um botão que, ao ser pressionado, coloca a View de destino na pilha de navegação. No iOS 16+ é recomendado usar NavigationLink com value e NavigationDestination em vez de destination diretamente para evitar a inicialização prematura das Views de destino.
Pontos principais
NavigationLink é uma View que inicia uma transição de navegação ao ser pressionada. Dentro do NavigationStack, pressionar NavigationLink coloca a tela de destino na pilha e exibe o botão Voltar do sistema. NavigationLink existe desde o iOS 13 e é o método principal de navegação do usuário no SwiftUI.
NavigationLink não herda de UIButton — é uma View do SwiftUI que se adapta automaticamente ao contexto. Dentro de List, NavigationLink é exibido com um indicador de divulgação. Fora de uma lista, NavigationLink se comporta como um botão normal, mas com comportamento de navegação.
De acordo com SwiftUI Lab (2024), NavigationLink é uma das Views mais usadas em aplicações SwiftUI, perdendo apenas para Text, Image e VStack. Entender as diferenças entre as formas de inicialização é crítico para o desempenho e o comportamento previsível da navegação.
Ao ser pressionado, NavigationLink adiciona um valor (ou destination) à pilha de navegação associada ao NavigationStack ou NavigationView mais próximo. O SwiftUI usa EnvironmentValue para passar o caminho de navegação pela hierarquia de Views. NavigationLink lê esse caminho do Environment e o modifica ao ser pressionado.
NavigationLink tem duas formas principais: com destination (especificando diretamente a View de destino) e com value (valor para NavigationDestination). A escolha da forma depende da versão do iOS e da arquitetura de navegação.
| Forma | Inicializador | iOS 13–15 | iOS 16+ |
|---|---|---|---|
| Destination | NavigationLink(destination:label:) | Recomendada | Não recomendada |
| Value | NavigationLink(value:label:) | Não disponível | Recomendada |
| IsActive | NavigationLink(isActive:destination:label:) | Navegação programática | Não recomendada |
Forma destination (iOS 13+): NavigationLink(destination: DetailView(), label: { Text("Open") }). Esta forma cria DetailView imediatamente ao renderizar NavigationLink, mesmo que o usuário não tenha clicado no link. Isso leva à inicialização prematura da View e a possíveis problemas de desempenho se a View de destino realizar operações pesadas em seu inicializador.
Forma value (iOS 16+): NavigationLink(value: "detail_42", label: { Text("Open") }). A View de destino é criada apenas quando o link é pressionado, quando o SwiftUI encontra o .navigationDestination correspondente. Isso evita a inicialização prematura e torna a navegação mais previsível.
NavigationLink com NavigationStack no iOS 16+ requer a mudança para a forma value. Você define um tipo de dados para navegação (String, Int, enum Route) e registra o destino através de .navigationDestination. NavigationLink apenas coloca o valor na pilha, e o SwiftUI cria a View de destino ao pressionar.
struct CatalogView: View {
let categories: [String]
var body: some View {
List(categories, id: \.self) { category in
NavigationLink(value: category) {
Text(category)
}
}
.navigationDestination(for: String.self) { category in
CategoryView(name: category)
}
}
}
// Programmatic navigation:
struct DeepLinkView: View {
@State private var path: [AppRoute] = []
var body: some View {
NavigationStack(path: $path) {
HomeView()
.navigationDestination(for: AppRoute.self) { route in
switch route {
case .detail(let id): DetailView(id: id)
case .settings: SettingsView()
}
}
.toolbar {
Button("Open Settings") {
path.append(AppRoute.settings)
}
}
}
}
}
Navegação programática: adicionar um valor ao caminho (através de path.append) equivale a pressionar um NavigationLink com o mesmo valor. Isso permite implementar navegação a partir de ViewModel, Coordinator ou em resposta a notificações push.
Forma IsActive (NavigationLink(isActive:destination:label:)) está disponível para compatibilidade, mas não é recomendada no iOS 16+. Use a forma value com Binding a um array de caminho ou NavigationPath.
NavigationLink em List exibe automaticamente um indicador de divulgação (chevron) no lado direito da linha, sinalizando ao usuário que pressionar levará a outra tela. A List gerencia a exibição da seta automaticamente — ao contrário de um NavigationLink normal fora de uma lista, onde não há seta.
Com iOS 16, List com NavigationLink usa automaticamente a forma value dentro de List(data:rowContent:). Ao usar ForEach dentro de List, o indicador de divulgação também é adicionado automaticamente. Este comportamento não pode ser desativado através de modificadores — apenas substituir NavigationLink por Button pode remover a seta.
Problema com a forma destination em List: se você usar NavigationLink(destination:label:) dentro de List, todas as Views de destino são criadas imediatamente ao carregar a lista, independentemente de o usuário ter clicado no link ou não. Para listas com um grande número de linhas, isso pode diminuir significativamente o carregamento inicial e aumentar o consumo de memória. A forma value com NavigationStack resolve este problema.
De acordo com WWDC 2022 (Session 10054), a Apple recomenda usar NavigationStack e a forma value do NavigationLink para novos projetos. Isso é especialmente importante para List com dados dinâmicos, onde o número de linhas pode ser grande.
Padrão 1: Aparência personalizada do NavigationLink. NavigationLink aceita qualquer View como label, permitindo criar designs personalizados para o link. Dentro de List, isso é especialmente conveniente — você obtém um indicador de divulgação automático ao usar NavigationLink.
NavigationLink(value: ProductRoute.detail(product)) {
HStack {
AsyncImage(url: product.imageURL)
.frame(width: 60, height: 60)
VStack(alignment: .leading) {
Text(product.name).font(.headline)
Text(product.price) .foregroundColor(.secondary)
}
}
.padding(8)
}
Padrão 2: NavigationLink sem seta (botão personalizado). Se você não precisar de um indicador de divulgação, use Button para navegação programática: path.append(value). Isso é útil para elementos de interface personalizados onde NavigationLink parece não natural.
Padrão 3: Navegação condicional. Você pode bloquear NavigationLink usando um destination vazio ou não adicionando .navigationDestination para certos valores. A navegação programática através do caminho permite verificar condições antes de adicionar um valor.
De acordo com Hacking with Swift (2024), a maioria dos problemas com NavigationLink está relacionada ao uso da forma destination em projetos antigos. Ao migrar para NavigationStack, substitua todos os NavigationLink(destination:label:) por NavigationLink(value:label:) e adicione .navigationDestination no nível raiz.
Perguntas frequentes
NavigationLink é uma View para transição para outra tela no SwiftUI. Ao ser pressionado, coloca a tela de destino na pilha de navegação NavigationStack ou NavigationView. Suporta duas formas: com destination (View de destino) e com value (valor de roteamento).
Forma value (iOS 16+) é preferível: a View de destino é criada apenas ao pressionar, não ao renderizar o link. A forma destination cria a View imediatamente, o que pode causar problemas de desempenho. Para projetos iOS 16+, use value + NavigationDestination.
SwiftUI adiciona automaticamente um indicador de divulgação (seta) ao NavigationLink dentro de List, sinalizando a possibilidade de navegação. Este comportamento não pode ser desativado. Se a seta não for necessária, use Button com navegação programática via path.append().
Use NavigationStack com um Binding de caminho e adicione valores via path.append(value). Isso equivale a pressionar um NavigationLink com o mesmo value. A navegação programática permite implementar deeplinks, notificações push e o padrão Coordinator.
A forma destination pode afetar o desempenho se as Views de destino realizarem operações pesadas em seu inicializador — todos os destinos são criados ao renderizar a lista. A forma value com NavigationStack resolve este problema criando Views apenas ao pressionar. Para listas com 50+ linhas, a diferença é significativa.
Resumo
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.
Leia também