SwiftUI, le cadre déclaratif d'Apple pour la construction d'interfaces utilisateur sur toutes les plateformes Apple, fournit une façon puissante mais simple de créer des interfaces multi-onglets. La navigation Tabbed est l'un des modèles les plus courants dans les applications mobiles et de bureau, permettant aux utilisateurs de passer rapidement entre des sections distinctes sans perdre de contexte. Que vous construisiez une application de nouvelles riche en contenu, un tableau de bord de productivité ou un panneau de paramètres, TabView est le composant go‐to pour mettre en œuvre la navigation onglet.

Cet article vous permet de découvrir tout ce que vous devez savoir sur la conception d'interfaces multi-tab avec SwiftUI. À partir des bases de TabView, nous explorerons la personnalisation, la gestion d'état, les modèles avancés, l'accessibilité, les performances et les exemples du monde réel.

Comprendre le composant TabView

Au cœur de la navigation de l'onglet dans SwiftUI se trouve TabView. C'est une vue conteneur qui présente un ensemble de vues enfant, chacune associée à un élément de l'onglet. Lorsque l'utilisateur touche un onglet, la vue correspondante est affichée, et la barre de l'onglet affiche l'état actif avec un point fort.

La disposition et le comportement

Par défaut, TabView rend une barre d'onglets en bas de l'écran sur iOS et en haut sur macOS. iPadOS s'adapte à l'orientation de l'appareil, et watchOS utilise un style segmenté. Vous n'avez pas besoin de gérer la mise en page de la barre d'onglets elle-même ; SwiftUI gère le positionnement, le calibrage et l'animation de la sélection de l'onglet.

Éléments de l'onglet avec des symboles SF

Apple recommande d'utiliser des symboles SF pour les icônes des onglets car ils s'échellent parfaitement sur les appareils et les paramètres d'accessibilité. Le modificateur accepte un constructeur de vue où vous placez habituellement un avec un nom de symbole SF et une étiquette . Par exemple :

TabView {
 ContentView()
 .tabItem {
 Label("Home", systemImage: "house.fill")
 }
}

La vue Label combine automatiquement une icône et un titre, assurant un alignement et des étiquettes d'accessibilité appropriées. Vous pouvez toujours revenir à des vues séparées et pour plus de contrôle.

Construire une interface multi-onglets de base

Créer une application simple avec onglet ne nécessite que quelques lignes de code. Let , construit un exemple minimal avec trois onglets : Accueil, Recherche et Profil.

Mise en œuvre étape par étape

  1. Créer une nouvelle vue SwiftUI (p. ex. ) et ajouter un TabView[ comme racine.
  2. Pour chaque onglet, fournir une vue enfant (comme une ou une vue personnalisée).
  3. Joindre le modificateur avec un symbole SF approprié et une chaîne localisée.

Exemple de code

struct ContentView: View {
 var body: some View {
 TabView {
 HomeView()
 .tabItem {
 Label("Home", systemImage: "house.fill")
 }

 SearchView()
 .tabItem {
 Label("Search", systemImage: "magnifyingglass")
 }

 ProfileView()
 .tabItem {
 Label("Profile", systemImage: "person.crop.circle")
 }
 }
 }
}

struct HomeView: View {
 var body: some View {
 Text("Welcome Home")
 }
}

struct SearchView: View {
 var body: some View {
 Text("Find what you need")
 }
}

struct ProfileView: View {
 var body: some View {
 Text("Your profile")
 }
}

Ce code produit une barre d'onglets de travail avec trois éléments. Chaque onglet affiche son contenu respectif lorsqu'il est sélectionné. SwiftUI gère automatiquement les animations d'état actif et de transition.

Personnalisation des éléments de l'onglet

Bien que l'apparence par défaut soit propre, vous devez souvent adapter la barre d'onglets pour correspondre à votre marque apps ou fournir des commentaires supplémentaires de l'utilisateur.

Ajout d'insignes et d'indicateurs

SwiftUI vous permet d'attacher un badge à n'importe quel onglet en utilisant le modificateur sur la vue enfant. Les insignes affichent un petit nombre ou un texte (comme le nombre de notifications non lues). Par exemple :

TabView {
 InboxView()
 .tabItem { Label("Inbox", systemImage: "tray.fill") }
 .badge(5) // Shows a red badge with "5"

 SettingsView()
 .tabItem { Label("Settings", systemImage: "gearshape") }
}

Les insignes sont automatiquement mis à jour lorsqu'ils sont liés à un @State ou à une propriété observée. Sur iOS, le badge apparaît comme un cercle rouge avec un numéro; sur d'autres plateformes, il peut être rendu différemment.

Modification de l'apparence de la barre d'onglet (couleurs et arrière-plan en pointe)

Pour modifier la couleur de l'accent de l'onglet sélectionné, définissez le modificateur sur le TabView (déprécié dans les versions iOS plus récentes) ou utilisez le modificateur dans iOS 15+:

TabView {
 // tabs...
}
.tint(.purple)

Pour une personnalisation plus avancée, comme un fond ou une forme personnalisée, vous pouvez utiliser par ou construire une barre d'onglets entièrement personnalisée à l'aide d'une pile horizontale de boutons (voir la section de la barre d'onglets personnalisée plus tard).

Gestion de l'État et sélection

Le contrôle de l'onglet actif est essentiel pour les fonctionnalités telles que le lien profond, les préférences de l'utilisateur, ou la réinitialisation de l'application vers le premier onglet après une certaine action.

Utilisation de @State pour la sélection

Reliez une variable @State du même type que les valeurs de tag au paramètre de TabView. Assignez à chaque enfant une valeur entière (ou une valeur ) en utilisant le modificateur .

struct ContentView: View {
 @State private var selectedTab = 0

 var body: some View {
 TabView(selection: $selectedTab) {
 HomeView()
 .tabItem { Label("Home", systemImage: "house.fill") }
 .tag(0)

 SearchView()
 .tabItem { Label("Search", systemImage: "magnifyingglass") }
 .tag(1)

 ProfileView()
 .tabItem { Label("Profile", systemImage: "person.crop.circle") }
 .tag(2)
 }
 }
}

Lorsque change (par exemple, via un bouton sur l'écran d'accueil), la vue de l'onglet bascule automatiquement vers l'onglet correspondant. Cette approche vous permet également de lire l'onglet actuel ailleurs dans votre application.

Commutateur d'onglet programmatique

Vous pouvez changer d'onglets depuis n'importe quel point de vue enfant en passant une liaison à la variable de sélection. Par exemple, un bouton --Aller à Paramètres de l'onglet d'accueil :

struct HomeView: View {
 @Binding var selectedTab: Int

 var body: some View {
 VStack {
 Text("Home")
 Button("Open Settings") {
 selectedTab = 2
 }
 }
 }
}

Intégrez ceci en passant la liaison lors de la création de la vue enfant à l'intérieur du TabView. Cela vous donne le plein contrôle de navigation sans casser l'état de l'onglet.

Sélection d'onglets en permanence avec UserDefaults

Pour une touche conviviale, rappelez-vous le dernier onglet sélectionné après le redémarrage de l'application. Utilisez pour persister automatiquement la sélection à [UserDefaults:

struct ContentView: View {
 @AppStorage("selectedTab") private var selectedTab = 0

 var body: some View {
 TabView(selection: $selectedTab) {
 // tabs...
 }
 }
}

L'application va maintenant lancer sur l'onglet que l'utilisateur a visité en dernier.

Patterns de navigation avancés

Les applications multi-tabs doivent souvent s'intégrer aux piles de navigation, gérer les URLs entrantes ou partager des données entre les onglets.

Combiner TabView avec NavigationView

Chaque onglet peut contenir ses propres (ou ] dans l'ancien SwiftUI). Cela permet de percer dans les vues de détail dans un onglet pendant que la barre d'onglet reste visible.

struct HomeView: View {
 var body: some View {
 NavigationStack {
 List(1..<20) { item in
 NavigationLink("Item \(item)", value: item)
 }
 .navigationDestination(for: Int.self) { item in
 DetailView(item: item)
 }
 .navigationTitle("Home")
 }
 }
}

Placez la dans l'onglet , pas à l'extérieur de la TabView[, pour maintenir des piles de navigation séparées par onglet. C'est le modèle recommandé pour les applications comme Mail ou Paramètres.

Manipulation des liens profonds

Lorsque votre application reçoit un lien universel ou un schéma d'URL personnalisé, vous pouvez avoir besoin de passer à un onglet spécifique et de naviguer en option vers une sous-vue. Utilisez le modificateur sur le TabView[ (ou la vue racine) et analysez l'URL pour mettre à jour l'état de sélection ou la navigation de déclenchement.

TabView(selection: $selectedTab)
 .onOpenURL { url in
 // e.g., myapp://tab/2
 if let tabNumber = extractTab(from: url) {
 selectedTab = tabNumber
 }
 }

Pour des scénarios plus complexes, combiner avec une liaison de chemin .

Passage de données entre les onglets

Comme chaque onglet a sa propre hiérarchie de vue, le passage de données entre eux nécessite une source d'état partagée. Les options incluent:

  • Objets environnementaux[: Injecter un via à la racine du TabView.
  • StateObject avec un gestionnaire partagé : Créez une classe monoton ou observable et passez-la.
  • Utilisation de la liaison de sélection[: Pour des valeurs simples, l'état de sélection lui-même peut agir comme un canal de communication (par exemple, -I change d'onglet 2 parce que les données sont prêtes).

Évitez les complications excessives; gardez le flux de données unidirectionnel lorsque possible.

Accessibilité et expérience utilisateur

Une interface d'onglet accessible est essentielle pour atteindre le plus grand public. SwiftUI fournit un support d'accessibilité intégré, mais vous devriez le vérifier et l'améliorer.

Support VoiceOver

Les éléments de l'onglet obtiennent automatiquement des étiquettes d'accessibilité à partir du Label[ ou du texte que vous fournissez. Testez que chaque onglet transmet clairement son but. Pour les barres d'onglets personnalisées, ajoutez et pour imiter le comportement du système.

Sur iPadOS avec clavier matériel, les utilisateurs peuvent naviguer entre les onglets en utilisant Command‐[numéro] ou Option‐Tab. SwiftUI=S TabView[ hérite automatiquement de ce comportement. Assurez-vous que votre implémentation d'onglets personnalisés supporte également les commandes du clavier en ajoutant des modificateurs .

Mises en page adaptatives

Sur les iPhones en mode paysage, la barre d'onglets peut apparaître différemment. iOS 15 et plus tard permettent à la barre d'onglets de compacter lorsque l'espace est limité. Vous pouvez ajuster le contenu de l'onglet avec pour offrir une meilleure expérience de lecture ou d'interaction.

Barres d'onglet personnalisées avec SwiftUI

Parfois, vous avez besoin d'un design qui s'écarte de la barre d'onglet système — par exemple, un bouton flottant au milieu, une forme incurvée, ou des icônes animées.

Replication de TabView avec des formes personnalisées

Créez une vue personnalisée en utilisant un de boutons superposés en bas. Utilisez pour la sélection et le changement de contenu avec une propriété calculée ou une déclaration à l'intérieur d'un .

struct CustomTabView: View {
 @State private var selection = 0

 var body: some View {
 VStack(spacing: 0) {
 // Content area
 Group {
 if selection == 0 {
 HomeView()
 } else if selection == 1 {
 SearchView()
 } else {
 ProfileView()
 }
 }
 .frame(maxWidth: .infinity, maxHeight: .infinity)

 // Custom tab bar
 HStack {
 TabBarButton(icon: "house.fill", label: "Home", isSelected: selection == 0)
 .onTapGesture { selection = 0 }
 Spacer()
 TabBarButton(icon: "magnifyingglass", label: "Search", isSelected: selection == 1)
 .onTapGesture { selection = 1 }
 Spacer()
 TabBarButton(icon: "person.fill", label: "Profile", isSelected: selection == 2)
 .onTapGesture { selection = 2 }
 }
 .padding(.horizontal)
 .padding(.top, 8)
 .background(Color(uiColor: .systemBackground)
 .shadow(radius: 2))
 }
 .ignoresSafeArea(.keyboard) // Prevent tab bar from moving with keyboard
 }
}

Transitions d'onglets d'animation

Ajoutez des transitions lisses lors du changement d'onglets en enveloppant le contenu dans un bloc . Par exemple, ajoutez une transition de diapositive ou d'opacité. Vous pouvez également animer l'icône elle-même en utilisant sur iOS 17+ (comme rebond ou impulsion).

Optimisation des performances

Les applications multi-tab peuvent souffrir de bloat mémoire si vous chargez tous les onglets avec impatience. SwiftUIS TabView[ est par défaut paresseux : il crée et rend la vue pour l'onglet sélectionné. Cependant, si vous utilisez des vues lourdes d'état, vous pouvez toujours vouloir optimiser.

Contenu de l'onglet de chargement paresseux

Utilisez ou dans les onglets pour reporter la création de la vue jusqu'à la défilement. Évitez d'utiliser des calculs complexes dans l'initialisateur des vues des enfants de l'onglet; au lieu de cela, vous pouvez vous fier à pour commencer le chargement des données.

Éviter les fuites de mémoire

Parce que les onglets contiennent souvent des références à des instances , assurez-vous que vous ne créez pas des cycles de référence inutiles. Utilisez pour les objets appartenant à la société et pour les objets partagés. Si un onglet n'est jamais affiché, sa vue peut toujours être conservée en mémoire — utilisez (un wrapper personnalisé) pour reporter l'initialisation jusqu'à ce que l'onglet soit sélectionné.

Tester votre interface Tabbed

Les tests automatisés permettent de s'assurer que la navigation des onglets fonctionne correctement dans tous les états de l'appareil.

Essais unitaires pour la sélection des onglets

Comme votre vue onglet est conduite par une variable , vous pouvez tester la logique qui change . Par exemple, valider qu'un lien profond analyse correctement et assigne l'index onglet.

func testTabSelectionViaDeepLink() {
 let url = URL(string: "myapp://tab/2")!
 let tabNumber = extractTab(from: url)
 XCTAssertEqual(tabNumber, 2)
}

Tests d'interface utilisateur avec XCTest

Utilisez XCUITest pour vérifier que le fait de taper un onglet affiche le contenu correct. Accédez aux onglets par leur étiquette ou leur identifiant d'accessibilité.

func testTappingSearchTab() {
 let app = XCUIApplication()
 app.launch()

 let searchTab = app.tabBars.buttons["Search"]
 XCTAssertTrue(searchTab.exists)
 searchTab.tap()
 XCTAssertTrue(app.staticTexts["Find what you need"].exists)
}

Exemple réel-mondial: un tableau de bord multi-tab

Let , tout est associé à un exemple pratique : une application de tableau de bord avec trois onglets – Aperçu, Analytique et Paramètres.

Aperçu

Affiche un résumé des paramètres clés (comme les utilisateurs actifs quotidiens, les revenus) dans un fichier défileable . Utilise pour permettre le forage dans des rapports détaillés. La sélection des onglets est maintenue avec .

Onglet analytique

Contient des graphiques et des graphiques construits avec des graphiques Swift. Comme le rendu des graphiques peut être lourd, marquez la vue comme et déclenchez le chargement des données seulement lorsque l'onglet apparaît.

Onglet Paramètres

Affiche une liste de toggles, de liens et d'un bouton de déconnection. Cet onglet peut avoir besoin d'accéder à un objet d'environnement contenant la session utilisateur. Passer cela par permet à tous les onglets de partager les mêmes données.

Pièges et solutions communs

Même les développeurs SwiftUI expérimentés rencontrent quelques problèmes récurrents avec TabView.

Barre d'onglets Disparu dans la pile de navigation

Si vous poussez une vue sur une pile de navigation à l'intérieur d'un onglet, la barre d'onglets peut disparaître sur le bouton Pousser. Solution : utilisez (iOS 16+) au lieu de – la barre d'onglets reste visible.

Valeurs d'étiquette incorrectes

Si vous n'assigner à chaque enfant, la vue de l'onglet peut ne pas honorer correctement la liaison de sélection. Toujours fournir une étiquette de hachage distincte pour chaque onglet.

État de réinitialisation de l'onglet

Parfois, lorsque vous changez d'onglets, l'état de la vue enfant=s se réinitialise. C'est par conception – SwiftUI crée une nouvelle instance de la vue enfant chaque fois qu'il doit l'afficher. Pour préserver l'état à travers les commutateurs d'onglets, soulevez l'état dans une vue parent ou utilisez à un niveau au-dessus de TabView.

Conclusion

La conception d'une interface multi-tab avec SwiftUI est à la fois simple et profondément personnalisable. Le composant TabView vous donne une base solide, et avec quelques lignes de code supplémentaires, vous pouvez ajouter des badges, gérer l'état, intégrer des piles de navigation, et même construire des barres d'onglets entièrement personnalisées. En suivant les meilleures pratiques pour l'accessibilité, la performance et les tests, vous créerez une expérience de navigation polie qui s'étend sur toutes les plateformes Apple.

Continuer à explorer en plongeant dans Apple officiellement TabVoir la documentation[, en apprenant les lignes directrices d'interface humaine pour les barres de onglet, et en expérimentant les symboles du FS pour donner à vos onglets un aspect poli et cohérent avec le système.