12

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 2

21

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

Sign up to request clarification or add additional context in comments.

6 Comments

I would recommend using enums just to make it look cleaner :)
@Rikh: you mean using enum in tag and instead of Integer, right?
Yep! Enum to keep track of current tab as well. Kinda like @State private var current : Tabs
Yes, that is certainly an option. Not sure how much 'cleaner' it looks since unfortunately the tag() doesn't do type inference based on the selection type. Maybe in a future version of SwiftUI. I went with Int because that's what the OP's question was set up as.
Wow this is great. I thought the tag was only a reference for the developer and I'd have to get and translate it into the $pageIndex somehow, but it already does that!
|
5

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!

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.