SwiftUI: Segmented Control scrolling inside tabs

I'm using a segmented control to navigate between tabs. My issue is, when I scroll inside one tab, all the other tabs are also strolling. Which is something I don't want.

I want that the scrolling works only inside the selected tab and when I click on the other tabs, it shows the top of the content of the selected tab.

Check attached video : https://imgur.com/a/Oxka4hv


struct ContentView: View {
    
    @State var selectedState = 0
    @State var showTopTabBar: Bool = false
    
    var body: some View {
        
        ZStack (alignment: . top){
            
            ScrollView (showsIndicators: false){
                
                Text("Welcome")
                    .frame(height: 300)
                
                Picker("Options", selection: $selectedState) {
                    Text("First").tag(0)
                    Text("Second").tag(1)
                    Text("Third").tag(2)
                }
                .pickerStyle(SegmentedPickerStyle())
                .background(Color.white)
                .opacity(showTopTabBar ? 0 : 1)
                .readPos { rect in
                    if showTopTabBar != (rect.minY <= 100) {
                        showTopTabBar.toggle()
                    }
                }
                
                if (selectedState==0) {
                    
                    FirstView()
                    
                }
                
                else if (selectedState==1){
                    Secondview()
                }
                
                else {
                    ThirdView()
                }
                
                Spacer()
                
            }
            .padding()
            
            Picker("Options", selection: $selectedState) {
                Text("First").tag(0)
                Text("Second").tag(1)
                Text("Third").tag(2)
            }
            .pickerStyle(SegmentedPickerStyle())
            .padding()
            .background(Color.white)
            .opacity(showTopTabBar ? 1 : 0)
            
        }
    }
}


struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}


extension View {
    
    func readPos(onChange: @escaping (CGRect) -> Void) -> some View {
        background(
            GeometryReader { geometryProxy in
                Color.clear
                    .preference(key: CoordinatesPreferenceKey.self, value: geometryProxy.frame(in: .global))
            }
        )
            .onPreferenceChange(CoordinatesPreferenceKey.self, perform: onChange)
    }
    
}


private struct CoordinatesPreferenceKey: PreferenceKey {
    static var defaultValue: CGRect = .zero
    static func reduce(value: inout CGRect, nextValue: () -> CGRect) {}
}

and here is my code

Thanks!

Answered by Claude31 in 707440022

It seems you have to use ScrollViewReader

https://stackoverflow.com/questions/60855852/how-to-scroll-list-programmatically-in-swiftui/60855853#60855853

However, I tried to implement in .onAppear, but it doesn't work either, because onAppear is called too early. I tried Dispatch with delay, to no avail.

https://stackoverflow.com/questions/71360905/calling-scrollto-in-onappear-doesnt-always-work

But maybe you will find a solution with those hints.

Could you show FirstView… so that we can test ?

    
    var body: some View {
        
        ScrollView (showsIndicators: false){
            ForEach(0 ..< 500) { item in
                HStack {
                    Spacer()
                    Text("First Tab")
                        .frame(height: 50)
                    Spacer()

                }
                .background(Color.red)

            }
        }
    }
}

I do not reproduce the problem. When I change tab, the List appears from top…

I scroll First:

Then I select Second

The problem comes when you scroll the whole window.

Accepted Answer

It seems you have to use ScrollViewReader

https://stackoverflow.com/questions/60855852/how-to-scroll-list-programmatically-in-swiftui/60855853#60855853

However, I tried to implement in .onAppear, but it doesn't work either, because onAppear is called too early. I tried Dispatch with delay, to no avail.

https://stackoverflow.com/questions/71360905/calling-scrollto-in-onappear-doesnt-always-work

But maybe you will find a solution with those hints.

SwiftUI: Segmented Control scrolling inside tabs
 
 
Q