Search code examples
swiftswiftuitabviewswipe-gestureswiftui-tabview

Disable Tab View Swipe to Change Page in SwiftUI 2.0


I am using a tab view in my SwiftUI app. I want to disable its swipe to left and write to move to other pages. I checked this answer and also checked this one, but none of them works. They are using

.gesture(DragGesture())

which is disabling the left swipe. I want to disable both left and right swipe.

I also tried:

.disabled(true)

which is disabling the whole view. There are buttons on my view to perform some tasks. This disabled them too.

My code is:

@State var selectedIndex = 0

var body: some View {

 TabView(selection: $selectedIndex) {
                
                FirstView().tag(0).gesture(DragGesture())
                
                SecondView().tag(1).gesture(DragGesture())
                
                ThirdView().tag(2).gesture(DragGesture())
                
            }.tabViewStyle(.page(indexDisplayMode: .never))
    }

My FirstView code is:

func firstView() -> some View {
        
        VStack(alignment: .leading) {
     
            HStack {
                
                Text("Is this a live claim?")
                    .font(.custom(InterFont.bold.rawValue, size: 24))
                
                Spacer()
                
            }.padding()
            
            
            Spacer()
            
            BlueButton(title: "Continue") {
                
               print("pressed")
            }.padding()
            
        }.ignoresSafeArea(edges: .top)
    }

My SecondView code is:

func secondView() -> some View {
        
        VStack(alignment: .leading) {
            
            HStack {
                Text("Detail of the incident")
                    .font(.custom(InterFont.bold.rawValue, size: 24))
                
                Text("(Optional)")
                    .font(.custom(InterFont.regular.rawValue, size: 14))
                
            }.padding()
            
            VStack(alignment: .leading) {
                
                Text("Detail of the incident")
                    .font(.custom(InterFont.regular.rawValue, size: 16))
                
                
                Spacer()
                
                BlueButton(title: "Continue", action: {
                    print("continue pressed")
                })
                
            }.padding()
            
        }.ignoresSafeArea(edges: .top)
    }

My ThirdView code is:

func thirdView() -> some View {
        
            
                VStack(alignment: .leading, spacing: 20) {
                
                    VStack(spacing: -10) {
                        HStack{
                            
                            Text("Call Police Crime Number")
                                .font(.custom(InterFont.bold.rawValue, size: 14))
                            
                            Spacer()
                            
                            Text("101")
                                .font(.custom(InterFont.bold.rawValue, size: 14))
                                .underline()
                        }.padding()
                            
                    }
                    
                    Spacer()
                    
                    BlueButton(title: "Continue") {
                        
                            print("continue pressed")
                        
                    }.padding()
                 
                }.ignoresSafeArea(edges: .top)
                
            }

simulator

Does anyone has a solution for this?


Solution

  • Actually the issue is because your views are transparent, so gesture is ignored due to failed hit testing.

    The fix is to make it hit-testable explicitly with .contentShape modifier.

    Tested with Xcode 13.4 / iOS 15.5

    TabView(selection: $selectedIndex) {
                    
        FirstView().tag(0)
          .contentShape(Rectangle()).gesture(DragGesture())  // << here !!
        
        SecondView().tag(1)
          .contentShape(Rectangle()).gesture(DragGesture())
        
        ThirdView().tag(2)
          .contentShape(Rectangle()).gesture(DragGesture())
    
    }.tabViewStyle(.page(indexDisplayMode: .never))