Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SwiftUI How to gain access to ScrollViewReader's proxy when swiping TabView

Tags:

swiftui

Currently, I created a custom navigation where selecting individual tabs (Info, Pizza, etc), it'll swipe me to a new view. Basically a UIKit equivalent of UIPageViewController.

Something different that i did is that when a selecting a section, it will also animate the scrollView to center the text. So for example, if i select the "Pasta" section, it swipe me to the correct view and center the "Pasta" text in the scrollView. To implement that, I embed a ScrollViewReader within ScrollView to gain access to proxy and everytime i select the section, i call proxy.scrollTo to scroll to proper index. But How does TabView gain access to ScrollView's proxy? So now, when I swipe to new view, the text of next page gets selected, but scrollView wont scroll to index and center it.

Is there some way to notify view if TabView is swiped? So I can call scrollTo?

struct CustomNavigationView: View {
@State var activeIndex = 0
var body: some View {
    
    VStack(spacing: 0) {
        AppBar(index: self.$activeIndex)

        TabView(selection: self.$activeIndex,
                content:  {
                    First()
                        .tag(0)
                    RecommendationPage()
                        .tag(1)
                    NewView(text: "Third", color: Color.orange)
                        .tag(2)
                })

            ///Allows the swipe to happen
            .tabViewStyle(PageTabViewStyle(indexDisplayMode: .never))  
    }
    .animation(.default)
    .edgesIgnoringSafeArea(.all)
  }
}


struct AppBar: View {
@Binding var index: Int

var sections = ["Episode", "Related Shows", "About", "Info", "Pizza", "Hamburger", "Pasta", "I dont even know"] 

var body: some View {
    VStack(alignment: .leading) {
        
        Text("Home")
            ...
        
         ScrollView(.horizontal, showsIndicators: false, content: {
            ScrollViewReader { proxy in
                
                VStack(alignment: .leading) {
                    //Underline bar
                    ZStack(alignment: .leading) {
                        ...
                    }
                    
                    ///Sections
                    HStack(spacing: tabsSpacing) {
                        ForEach(0..<sections.count) { i in
                            Button(action: {
                                self.index = i
                                
                                withAnimation(.linear) {
                                    
                                    ///This checks ensures that when we select last 2 items, scrollView doesnt try to align selectedIndex to middle
                                    if i < sections.count - 2 {
                                        proxy.scrollTo(i, anchor: .center)
                                    } else if i == sections.count - 2 {
                                        proxy.scrollTo(i)
                                    } else {
                                        proxy.scrollTo(i, anchor: .trailing)
                                    }
                                }
                                
                            }, label: {
                                Text(sections[i])
                                   ...
                            })
                            .id(i)
                        }
                    }   
                }
            }
        })

section as a scrollView

like image 971
Kenny Ho Avatar asked Dec 20 '25 07:12

Kenny Ho


1 Answers

There is an open-source library that solves your problem. The scrollable style centers your selected tab.

https://github.com/xmartlabs/PagerTabStripView#scrollable-style

like image 132
Cecilia Pirotto Avatar answered Dec 24 '25 12:12

Cecilia Pirotto



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!