NavigationLink est un élément de contrôle dans SwiftUI conçu pour la transition vers un autre écran dans NavigationStack ou NavigationView. Selon Apple Developer Documentation, 2024, NavigationLink crée un bouton qui, lorsqu'on appuie dessus, place la View cible dans la pile de navigation. Sous iOS 16+, il est recommandé d'utiliser NavigationLink avec value et NavigationDestination plutôt qu'avec destination directement pour éviter l'initialisation prématurée des Views cibles.
Points clés
NavigationLink est une View qui initie une transition de navigation lorsqu'on appuie dessus. Dans NavigationStack, appuyer sur NavigationLink place l'écran cible sur la pile et affiche le bouton Retour système. NavigationLink existe depuis iOS 13 et est la méthode principale de navigation utilisateur dans SwiftUI.
NavigationLink n'hérite pas de UIButton — c'est une View SwiftUI qui s'adapte automatiquement au contexte. Dans List, NavigationLink s'affiche avec un indicateur de divulgation. En dehors d'une liste, NavigationLink se comporte comme un bouton normal mais avec un comportement de navigation.
Selon SwiftUI Lab (2024), NavigationLink est l'une des Views les plus utilisées dans les applications SwiftUI, derrière seulement Text, Image et VStack. Comprendre les différences entre les formes d'initialisation est essentiel pour les performances et un comportement de navigation prévisible.
Lorsqu'on appuie, NavigationLink ajoute une valeur (ou destination) à la pile de navigation associée au NavigationStack ou NavigationView le plus proche. SwiftUI utilise EnvironmentValue pour transmettre le chemin de navigation à travers la hiérarchie des Views. NavigationLink lit ce chemin depuis l'Environment et le modifie lorsqu'on appuie.
NavigationLink a deux formes principales : avec destination (spécifiant directement la View cible) et avec value (valeur pour NavigationDestination). Le choix de la forme dépend de la version d'iOS et de l'architecture de navigation.
| Forme | Initialisateur | iOS 13–15 | iOS 16+ |
|---|---|---|---|
| Destination | NavigationLink(destination:label:) | Recommandée | Non recommandée |
| Value | NavigationLink(value:label:) | Non disponible | Recommandée |
| IsActive | NavigationLink(isActive:destination:label:) | Navigation programmatique | Non recommandée |
Forme destination (iOS 13+) : NavigationLink(destination: DetailView(), label: { Text("Open") }). Cette forme crée DetailView immédiatement lors du rendu de NavigationLink, même si l'utilisateur n'a pas cliqué sur le lien. Cela entraîne une initialisation prématurée de la View et des problèmes de performance potentiels si la View cible effectue des opérations lourdes dans son initialisateur.
Forme value (iOS 16+) : NavigationLink(value: "detail_42", label: { Text("Open") }). La View cible n'est créée que lorsque le lien est pressé, lorsque SwiftUI trouve le .navigationDestination correspondant. Cela évite l'initialisation prématurée et rend la navigation plus prévisible.
NavigationLink avec NavigationStack sous iOS 16+ nécessite le passage à la forme value. Vous définissez un type de données pour la navigation (String, Int, enum Route) et enregistrez la destination via .navigationDestination. NavigationLink place uniquement la valeur sur la pile, et SwiftUI crée la View cible lors de l'appui.
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)
}
}
}
}
}
Navigation programmatique : ajouter une valeur au chemin (via path.append) équivaut à appuyer sur un NavigationLink avec la même valeur. Cela permet d'implémenter la navigation depuis ViewModel, Coordinator ou en réponse à des notifications push.
Forme IsActive (NavigationLink(isActive:destination:label:)) est disponible pour la compatibilité mais n'est pas recommandée sous iOS 16+. Utilisez la forme value avec Binding vers un tableau de chemin ou NavigationPath.
NavigationLink dans List affiche automatiquement un indicateur de divulgation (chevron) sur le côté droit de la ligne, signalant à l'utilisateur que l'appui mènera à un autre écran. List gère l'affichage de la flèche automatiquement — contrairement à un NavigationLink normal en dehors d'une liste, où il n'y a pas de flèche.
Avec iOS 16, List avec NavigationLink utilise automatiquement la forme value dans List(data:rowContent:). Lors de l'utilisation de ForEach dans List, l'indicateur de divulgation est également ajouté automatiquement. Ce comportement ne peut pas être désactivé via des modificateurs — seul le remplacement de NavigationLink par Button peut supprimer la flèche.
Problème avec la forme destination dans List : si vous utilisez NavigationLink(destination:label:) dans List, toutes les Views de destination sont créées immédiatement lors du chargement de la liste, que l'utilisateur ait cliqué sur le lien ou non. Pour les listes avec un grand nombre de lignes, cela peut ralentir considérablement le chargement initial et augmenter la consommation mémoire. La forme value avec NavigationStack résout ce problème.
Selon WWDC 2022 (Session 10054), Apple recommande d'utiliser NavigationStack et la forme value de NavigationLink pour les nouveaux projets. C'est particulièrement important pour List avec des données dynamiques, où le nombre de lignes peut être important.
Modèle 1 : Apparence personnalisée de NavigationLink. NavigationLink accepte n'importe quelle View comme label, permettant de créer des conceptions personnalisées pour le lien. Dans List, c'est particulièrement pratique — vous obtenez un indicateur de divulgation automatique lors de l'utilisation de 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)
}
Modèle 2 : NavigationLink sans flèche (bouton personnalisé). Si vous n'avez pas besoin d'indicateur de divulgation, utilisez Button pour la navigation programmatique : path.append(value). C'est utile pour les éléments d'interface personnalisés où NavigationLink semble peu naturel.
Modèle 3 : Navigation conditionnelle. Vous pouvez bloquer NavigationLink en utilisant une destination vide ou en n'ajoutant pas .navigationDestination pour certaines valeurs. La navigation programmatique via le chemin permet de vérifier les conditions avant d'ajouter une valeur.
Selon Hacking with Swift (2024), la plupart des problèmes avec NavigationLink sont liés à l'utilisation de la forme destination dans les projets plus anciens. Lors de la migration vers NavigationStack, remplacez tous les NavigationLink(destination:label:) par NavigationLink(value:label:) et ajoutez .navigationDestination au niveau racine.
Questions fréquentes
NavigationLink est une View pour la transition vers un autre écran dans SwiftUI. Lorsqu'on appuie, il place l'écran cible dans la pile de navigation NavigationStack ou NavigationView. Il prend en charge deux formes : avec destination (View cible) et avec value (valeur de routage).
Forme value (iOS 16+) est préférable : la View cible n'est créée qu'en appuyant, pas lors du rendu du lien. La forme destination crée la View immédiatement, ce qui peut causer des problèmes de performances. Pour les projets iOS 16+, utilisez value + NavigationDestination.
SwiftUI ajoute automatiquement un indicateur de divulgation (flèche) à NavigationLink dans List, signalant la possibilité de navigation. Ce comportement ne peut pas être désactivé. Si la flèche n'est pas nécessaire, utilisez Button avec navigation programmatique via path.append().
Utilisez NavigationStack avec un Binding de chemin et ajoutez des valeurs via path.append(value). Cela équivaut à appuyer sur un NavigationLink avec la même value. La navigation programmatique permet d'implémenter des liens profonds, des notifications push et le modèle Coordinator.
La forme destination peut affecter les performances si les Views cibles effectuent des opérations lourdes dans leur initialisateur — toutes les destinations sont créées lors du rendu de la liste. La forme value avec NavigationStack résout ce problème en créant les Views uniquement lors de l'appui. Pour les listes de 50+ lignes, la différence est significative.
Résumé
Nous développerons une application mobile clé en main
IT Sectr crée des applications iOS et Android pour les startups et les entreprises depuis 2017. Nous vous conseillerons et vous proposerons la meilleure solution.
Lisez aussi