SwiftUI, Apple's declarative framework voor het bouwen van gebruikersinterfaces op alle Apple-platforms, biedt een krachtige maar eenvoudige manier om multi-tab interfaces te maken. Tabbednavigatie is een van de meest voorkomende patronen in mobiele en desktop-apps, waardoor gebruikers snel kunnen schakelen tussen verschillende secties zonder de context te verliezen. Of u nu een content-heavy news-app, een productiviteitsdashboard of een instellingenpaneel bouwt, TabView[] is de go‐to component voor het implementeren van tabnavigatie.

Dit artikel gaat door alles wat je moet weten over het ontwerpen van multi-tab interfaces met SwiftUI. Beginnend met de basisprincipes van TabView, verkennen we maatwerk, state management, geavanceerde patronen, bereikbaarheid, prestaties en real-world voorbeelden. Tegen het einde, zal je uitgerust zijn om productie-ready tabbed apps die gebruikers plezier.

Het TabView-component begrijpen

In het hart van de navigatie van het tabblad in SwiftUI ligt TabView. Het geeft een containerweergave die een set van kindweergaven toont, elk geassocieerd met een tab-item. Wanneer de gebruiker een tabblad tikt, wordt de bijbehorende weergave weergegeven, en de tabbalk toont de actieve status met een highlight.

Opmaak en gedrag

Standaard, TabView geeft een tabbladbalk aan de onderkant van het scherm op iOS en aan de bovenkant op macOS. iPadOS past zich aan de oriëntatie van het apparaat aan, en watchOS gebruikt een gesegmenteerde stijl. U hoeft niet de lay-out van de tabbalk zelf te beheren; SwiftUI behandelt de positionering, grootte en animatie van de tabselectie.

Tab Items met SF-symbolen

Apple raadt aan om SF-symbolen te gebruiken voor tabpictogrammen omdat ze perfect over apparaten en toegankelijkheidsinstellingen schalen. De modifier accepteert een view builder waarbij je meestal een plaatst met een SF-symboolnaam en een label. Bijvoorbeeld:

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

Het Label-scherm combineert automatisch een pictogram en een titel, waardoor een juiste uitlijning en toegankelijkheidslabels gegarandeerd zijn. U kunt altijd terugvallen om en te scheiden van de weergaven voor meer controle.

Een basismulti-Tab-interface bouwen

Het maken van een eenvoudige tabbed-app vereist slechts een paar regels code. Laat ons een minimaal voorbeeld bouwen met drie tabbladen: Home, Zoeken en Profiel.

Stapsgewijze uitvoering

  1. Maak een nieuwe SwiftUI-weergave (bv. ) en voeg een TabView toe als de wortel.
  2. Geef voor elk tabblad een dochterweergave (zoals een of een aangepaste weergave).
  3. Bevestig de modifier met een passend SF-symbool en een gelokaliseerde string.

Codevoorbeeld

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

Deze code produceert een werktabblad met drie items. Elk tabblad toont de respectievelijke inhoud wanneer geselecteerd. SwiftUI beheert automatisch de actieve status- en transitieanimaties.

Tab-items aanpassen

Terwijl de standaard look schoon is, moet je vaak de tabbalk aanpassen om aan te passen aan je merk of extra feedback van de gebruiker.

Toevoegen van badges en indicatoren

SwiftUI stelt u in staat om een badge aan een tab-item te koppelen met behulp van de -modifier op de dochterweergave. Badges tonen een klein aantal of tekst (zoals het aantal ongelezen meldingen). Bijvoorbeeld:

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

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

Badges worden automatisch bijgewerkt wanneer ze gebonden zijn aan een @State of waargenomen eigenschap. Op iOS verschijnt de badge als een rode cirkel met een getal; op andere platformen kan het anders worden weergegeven.

Tabbladbalk uiterlijk wijzigen (kleuren en achtergrond)

Om de accentkleur van het geselecteerde tabblad te wijzigen, stelt u de -modifier op de TabView (achterhaald in nieuwere iOS-versies) in of gebruikt u de -modifier in iOS 15+:

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

Voor meer geavanceerde aanpassingen, zoals een aangepaste achtergrond of vorm, kunt u gebruiken via of een volledig aangepaste tabbladbalk bouwen met behulp van een horizontale stapel knoppen (zie de aangepaste tabbalk sectie later). Echter, vasthouden aan het systeemtabblad bar, waar mogelijk zorgt voor consistent gedrag met gebruikersverwachtingen en systeem-niveau gebaren.

Beheerstaat en selectie

Het controleren van welke tabblad actief is is essentieel voor functies zoals diepe koppeling, gebruikersvoorkeuren, of het resetten van de app naar het eerste tabblad na een bepaalde actie.

@State gebruiken voor selectie

Bind een @State variabele van hetzelfde type als de tagwaarden aan de parameter van TabView]. Geef elk kind een geheel getal (of een waarde ) toe met behulp van de -modifier.

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

Wanneer verandert (bijvoorbeeld via een knop op het startscherm), schakelt het tabbladscherm automatisch over op het bijbehorende tabblad. Deze aanpak laat u ook het huidige tabblad elders in uw app lezen.

Programmatische tab wisselen

U kunt tabbladen wijzigen van binnenuit een dochterweergave door een binding door te geven aan de selectie variabele. Bijvoorbeeld, een

struct HomeView: View {
 @Binding var selectedTab: Int

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

Integreer dit door de binding door te geven bij het maken van het kindbeeld in de TabView. Dit geeft u volledige controle over navigatie zonder de tabstatus te breken.

Tab-selectie met gebruikersinstellingen volhouden

Voor een gebruiksvriendelijke touch, onthoud het laatste geselecteerde tabblad na het herstarten van de app. Gebruik om automatisch de selectie te handhaven naar Gebruikersstandaarden:

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

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

De app zal nu starten op het tabblad dat de gebruiker het laatst bezochte.

Geavanceerde navigatiepatronen

Multi-tab apps moeten vaak integreren met navigatie stacks, inkomende URL's verwerken of gegevens delen tussen tabbladen.

TabView combineren met navigatieweergave

Elk tabblad kan zijn eigen .2]] (of in oudere SwiftUI bevatten), waardoor het mogelijk is om binnen een tabblad in detail te kijken terwijl de tabbalk zichtbaar blijft.

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

Plaats de in het tabblad dochterweergave, niet buiten de TabView, om aparte navigatiestapels per tab te behouden. Dit is het aanbevolen patroon voor apps zoals Mail of Instellingen.

Diepe koppelingen hanteren

Wanneer uw app een universele link of een aangepaste URL-schema ontvangt, moet u mogelijk overschakelen naar een specifiek tabblad en eventueel navigeren naar een sub-view. Gebruik de -modifier op de TabView (of de root-view) en ontleed de URL om de selectiestatus of triggernavigatie bij te werken.

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

Voor complexere scenario's, combineer met een padbinding.

Gegevens tussen tabbladen doorgeven

Omdat elk tabblad zijn eigen hiërarchie heeft, vereist het doorgeven van gegevens tussen hen een gedeelde bron van de staat. Opties zijn onder meer:

  • Milieuobjecten: Injecteer een via aan de wortel van de TabView.
  • StateObject met een gedeelde manager: Maak een singleton of waarneembare klasse aan en geef het door.
  • Met behulp van de selectiebinding: Voor eenvoudige waarden kan de selectiestaat zelf fungeren als communicatiekanaal (bijvoorbeeld . .Ik ben overgestapt naar tab 2 omdat de gegevens klaar zijn.

Vermijd overcompileren; houd de gegevensstroom, indien mogelijk, unidirectioneel.

Toegankelijkheid en gebruikerservaring

Een toegankelijke tab-interface is cruciaal voor het bereiken van het breedste publiek. SwiftUI biedt ingebouwde toegankelijkheidsondersteuning, maar je moet het controleren en verbeteren.

Ondersteuning voor spraakover

Tab items krijgen automatisch toegankelijkheidslabels van de Label of tekst die u verstrekt. Test of elk tabblad duidelijk zijn doel overbrengt. Voor aangepaste tabbladen voeg en toe om het systeemgedrag na te bootsen.

Op iPadOS met een hardware-toetsenbord kunnen gebruikers tussen tabbladen navigeren met behulp van Command-[nummer] of Optie-Tab. SwiftUI

Adaptieve indeling

Op iPhones in landschapsmodus kan de tabbalk anders verschijnen. iOS 15 en later laat de tabbalk compacter worden wanneer de ruimte beperkt is. U kunt de tabinhoud aanpassen met ] om een betere lees- of interactie-ervaring te bieden.

Aangepaste tabbladen met SwiftUI

Soms heb je een ontwerp nodig dat afwijkt van de systeemtabbladbalk . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

TabView met aangepaste vormen kopiëren

Maak een aangepaste weergave aan met een van knoppen onderaan overgelegd. Gebruik voor selectie en schakel inhoud met een berekende eigenschap of statement binnen een .

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

Tabbladovergangen animeren

Voeg soepele overgangen toe bij het schakelen van tabbladen door de inhoud in te pakken in een blok . Voeg bijvoorbeeld een dia of opaciteitsovergang toe. U kunt het pictogram zelf ook animeren met op iOS 17+ (zoals bounce of puls).

Prestatieoptimalisatie

Multi-tab apps kunnen lijden aan geheugen opgeblazen als u alle tabbladen gretig laden. SwiftUI

Lui laden van tabbladinhoud

Gebruik of binnen tabbladen om het aanmaken van het beeld uit te stellen tot het scrollen. Vermijd het gebruik van complexe berekeningen in de initialisatie van tabblad-kinderweergaven; vertrouw in plaats daarvan op ] om gegevens te laden.

Geheugenlekken vermijden

Omdat tabbladen vaak verwijzingen bevatten naar gevallen, zorg ervoor dat u geen onnodige sterke referentiecycli aanmaakt. Gebruik voor eigendomsobjecten en voor gedeelde objecten. Als een tab nooit wordt getoond, kan de weergave ervan nog steeds in het geheugen worden bewaard . Gebruik (een aangepaste wikkelaar) om de initialisatie uit te stellen totdat het tabblad is geselecteerd.

Uw Tabbed-interface testen

Automatische tests helpen ervoor te zorgen dat tab navigatie correct werkt in de apparaattoestanden.

Eenheidstests voor tabselectie

Omdat je tabweergave wordt aangedreven door een variabele, kun je de logica testen die verandert . Bijvoorbeeld, valideren dat een diepe link correct pareert en de tab index toewijst.

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

UI-tests met XCTest

Gebruik XCUITest om te controleren of het tikken op een tabblad item de juiste inhoud toont. Toegang tot tabbladen door hun label of toegankelijkheidsidentificatie.

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

Voorbeeld Real-World: Een multi-tab Dashboard

Laten we alles samenbrengen met een praktisch voorbeeld: een dashboard app met drie tabbladen . . Overzicht, Analytics, en Instellingen.

Overzichtstabblad

Toont een samenvatting van de belangrijkste metriek (zoals dagelijkse actieve gebruikers, inkomsten) in een scrollable . Gebruikt om te kunnen boren in gedetailleerde rapporten. De tabselectie wordt voortgezet met .

Tabblad analytics

Bevat grafieken en grafieken gebouwd met Swift Charts. Omdat grafiek rendering kan zwaar zijn, markeer het uitzicht als en trigger data laden alleen wanneer het tabblad verschijnt.

Instellingen

Toont een lijst met schakels, links en een afmeldknop. Dit tabblad heeft mogelijk toegang nodig tot een omgevingsobject dat de gebruikerssessie bevat. Door dat te passeren, zorgt ervoor dat alle tabbladen dezelfde gegevens delen.

Veel voorkomende Pitfalls en Oplossingen

Zelfs ervaren SwiftUI-ontwikkelaars komen een paar terugkerende problemen tegen met TabView.

Tabbladbalk verdwijnt in navigatiestack

Als u een weergave op een navigatiestapel in een tabblad duwt, kan de tabbalk verdwijnen bij het duwen. Oplossing: gebruik (iOS 16+) in plaats van ] De tabbalk blijft zichtbaar. Als alternatief, verberg/show de tabbalk handmatig met de modifier.

Onjuiste tagwaarden

Als u niet toewijst aan elk kind, kan het zijn dat de tab niet correct de selectiebinding eren. Geef altijd een aparte, hashable tag voor elk tabblad.

Tabblad Beeld Herstellen toestand

Soms bij het schakelen van tabbladen, de dochterweergave .staat resetten. Dit is door ontwerp . . SwiftUI creëert een nieuwe instantie van het kind weergave elke keer dat het moet worden weergegeven. Om de toestand te behouden over tab schakelaars, til de staat in een ouder uitzicht of gebruik op een niveau boven de TabView. Als alternatief, gebruik voor gedeelde gegevens die niet opnieuw moeten worden ingesteld.

Conclusie

Het ontwerpen van een multi-tab interface met SwiftUI is zowel eenvoudig als zeer aanpasbaar.De TabView component geeft je een solide basis, en met een paar extra regels code kun je badges toevoegen, status beheren, navigatie stacks integreren en zelfs volledig aangepaste tabbladen bouwen. Door de beste praktijken voor toegankelijkheid, prestaties en testen te volgen, creëer je een gepolijste navigatie-ervaring die over alle Apple platforms schalen.

Ga verder met het verkennen van Apple... officiële TabBekijk documentatie, leer meer over menselijke interface richtlijnen voor tabbladen, en experimenteer met SF Symbolen om je tabbladen een gepolijste, systeemconsistente blik te geven.