Search code examples
swiftuitabviewswiftui-tabview

Programmatic Tabview selection not working in SwiftUI


After loading and trying simple examples of programmatic tab selection (which worked), I was mystified why it was not working in my code. So I simplified my code down step by step to eliminate other possibilities, and now it is so simple it is almost the same as the working example, and certainly any aspects specific to my application have been removed. And it still doesn't work. Here's the code:

struct MyTabView: View {
  @State private var selTab = 1
  
  var body: some View {
    TabView(selection: $selTab) {
      Button("Goto Tab 2") { selTab = 2 }
        .tabItem { Label("Tab1", systemImage: "list.dash") }
      Text("Tab 2")
        .tabItem { Label("Tab2", systemImage: "list.dash") }
    }
  }
}

struct ContentView: View {
  var body: some View {
    MyTabView()
  }
}

When I press the "Goto Tab 2" button, the screen flashes, but the page does not change. Given the state of the Apple documentation, it isn't much help.

I'm completely baffled why this code doesn't work yet the simple example found via google does, when they look almost identical.


Solution

  • you forgot to add the modifer .tag

    struct MyTabView: View {
    @State private var selTab = 1
    
    var body: some View {
    TabView(selection: $selTab) {
      Button("Goto Tab 2") { selTab = 2 }
        .tabItem { Label("Tab1", systemImage: "list.dash") }
        .tag(1)
      Text("Tab 2")
        .tabItem { Label("Tab2", systemImage: "list.dash") }
        .tag(2)
      }
     }
    }
    

    To make cleaner is applied the architecure MVVM:

    enum TabBar: Int{
    
      case first = 0
      case second = 1
    }
    
    class TabBarViewModel: ObservableObject {
    
       @Published var currentTab: TabBar = .first
    
    }
    
    
    struct MyTabView: View {
    
      @StateObject private var tabBarVM = TabBarViewModel()
    
      var body: some View {
        TabView(selection: $tabBarVM.currentTab) {
          Button("Goto Tab 2") { tabBarVM.currentTab = .second }
          .tabItem { Label("Tab1", systemImage: "list.dash") }
          .tag(TabBar.first)
        Text("Tab 2")
          .tabItem { Label("Tab2", systemImage: "list.dash") }
          .tag(TabBar.second)
        
       }
     }
    }