2

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

Taimoor Arif
  • 750
  • 3
  • 19
  • 2
    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. – Asperi Jul 13 '22 at 07:34
  • I have the same issue did you find a solution / alternative to this? – Slamit Feb 15 '23 at 14:49
  • @Slamit No, I didn't find any solution yet. I used **NavigationLink** to move to next View instead of **Tab View**. – Taimoor Arif Feb 16 '23 at 05:11
  • @Asperi can you please look into this bug [https://stackoverflow.com/questions/76721545/swiftui-drag-gesture-cancel-state](https://stackoverflow.com/questions/76721545/swiftui-drag-gesture-cancel-state) – Taimoor Arif Jul 24 '23 at 07:19

1 Answers1

0

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 ".simulataneousGesture(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.

Slamit
  • 465
  • 1
  • 6
  • 21