Disable to Change Page On Swipe of Tab View in SwiftUI
Asked Answered
E

1

4

I am using Tab View in my SwiftUI app. I want the changing of page disabled, while swiping left or right. And I had achieved it from this. This works fine but the issue I am facing is I have a button on the bottom of every view, and when I try to swipe from the button, it is swiping left right. I want to disable it too but don't know how to do it. Here is my code:

struct TabViewTesting: View {
    
    @State var tabSelection = 0
    
    var body: some View {
       
        TabView(selection: $tabSelection) {
            
            firstView().tag(0).contentShape(Rectangle()).gesture(DragGesture())
            
            secondView().tag(1).contentShape(Rectangle()).gesture(DragGesture())
            
            thirdView().tag(2).contentShape(Rectangle()).gesture(DragGesture())
            
        }.tabViewStyle(.page(indexDisplayMode: .never))
    }
}

And this is the code for the Views:

extension TabViewTesting {
    
    func firstView() -> some View {
      
        VStack {
            Text("First screen")
            
            Spacer()
            
            Button {
                self.tabSelection = 1
            } label: {
                ZStack {
                    RoundedRectangle(cornerRadius: 20)
                        .frame(height: 50)

                    Text("move to 2nd view")
                        .foregroundColor(.white)
                }
            }.padding()

        }.background(.green)
    }
    
    func secondView() -> some View {
      
        VStack {
            Text("second screen")
            
            Spacer()
            
            Button {
                self.tabSelection = 2
            } label: {
                ZStack {
                    RoundedRectangle(cornerRadius: 20)
                        .frame(height: 50)
                    
                    Text("move to 3rd view")
                        .foregroundColor(.white)
                }
            }.padding()

        }.background(.red)
    }
    
    func thirdView() -> some View {
      
        VStack {
            Text("Third screen")
            
            Spacer()
            
            Button {
                self.tabSelection = 0
            } label: {
                ZStack {
                    RoundedRectangle(cornerRadius: 20)
                        .frame(height: 50)
                    
                    Text("move to first view")
                        .foregroundColor(.white)
                }
            }.padding()

        }.background(.yellow)
    }
}

And this is what happening:

simulator

Expostulate answered 13/7, 2022 at 7:29 Comment(4)
This really looks like a bug... probably blocking with drag gesture would work, but adding it to each button on screen is really weird... I would consider rejecting TabView usage and replacing with some custom solution.Schlemiel
I have the same issue did you find a solution / alternative to this?Terena
@Terena No, I didn't find any solution yet. I used NavigationLink to move to next View instead of Tab View.Expostulate
@Schlemiel can you please look into this bug https://mcmap.net/q/670570/-swiftui-drag-gesture-cancel-stateExpostulate
T
3

I actually found an answer in the comments of this question.

The issue is: any view that has an onTapGesture will ignore .gesture(DragGesture()).

The solution is to use .simultaneousGesture(DragGesture()) instead to ensure the gesture is capture and handled by both view/modifier.

It worked perfectly in my case after changing it. The only exception is for 2 finger drag gesture.

Terena answered 16/2, 2023 at 10:23 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.