SwiftUI how to keep track of page index in PageTabViewStyle?

Viewed 2319

I'm trying to keep track of what page the user is on in a TabView that is PageTabViewStyle in SwiftUI but I can't figure out the best way to keep track of the page index? Using .onAppear doesn't work well as it gets called multiple times and pages 2 and 3 get called even when not on the screen.

@State var pageIndex = 0

    var body: some View {
    VStack {
        Text("current page = \(0) ")
        TabView {
            Text("First")
                .onAppear {
                    pageIndex = 0
                }
            Text("Second")
            .onAppear {
                    pageIndex = 1
                }
            Text("Third")
            .onAppear {
                    pageIndex = 2
                }
        }
         .tabViewStyle(PageTabViewStyle(indexDisplayMode: .never))
         }
    }
}
2 Answers

You can pass a selection binding to the TabView and use tag to identify the pages:

struct ContentView: View {
    @State var pageIndex = 0
    
    var body: some View {
        VStack {
            Text("current page = \(pageIndex) ")
            TabView(selection: $pageIndex) {
                Text("First").tag(0)
                Text("Second").tag(1)
                Text("Third").tag(2)
            }
            .tabViewStyle(PageTabViewStyle(indexDisplayMode: .never))
        }
    }
}

Note that in your original code, it was always going to say current page = 0 because you weren't interpolating the pageIndex variable into the string

If you want to be able to get the current page/index and act on that data, what I found useful is using the .onChange() modifier on the view, like so.

TabView(selection: $currentIndex) {
     Text("First view")
         .tag(0)
                
     Text("Middle view")
         .tag(1)
                
     Text("Last view")
         .tag(2)
}
.tabViewStyle(.page(indexDisplayMode: .never))
.onChange(of: currentIndex) { newValue in
     print("New page: \(newValue)")
}

Hope that helps!

Related