4

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?

Taimoor Arif
  • 750
  • 3
  • 19
  • Show your tab views (or simplified demo for debug), because when I use instead just colors (.red, .green, .blue) then swipe is blocked in both directions. Xcode 13.4 / iOS 15.5. So I assume your issue is due to some conflicts with specific views. – Asperi Jun 23 '22 at 09:19
  • @Asperi I tried it with colors and it is working, but when I use my views. this is not working. I am attaching a video in my question – Taimoor Arif Jun 23 '22 at 09:35
  • I do believe you :) but video will not help to debug - if you want help you need to provide your code. – Asperi Jun 23 '22 at 09:38

1 Answers1

7

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))
Asperi
  • 228,894
  • 20
  • 464
  • 690
  • This works fine but there is an issue. I have a **button** at the **bottom** of every view, and when I tried to swipe from that button, the view is swiping. Is there any way to stop that too – Taimoor Arif Jul 12 '22 at 12:33
  • 2
    Well you can do it actually. If you have button at the bottom you can just use .simultaneousGesture(DragGesture()) instead of .gesture(DragGesture()) combined with .contentShape(Rectangle()) – Azraith Sherkhan Oct 28 '22 at 10:14
  • This does not work. See issue here: https://stackoverflow.com/questions/72962447/disable-to-change-page-on-swipe-of-tab-view-in-swiftui – Binh Ho Nov 11 '22 at 09:06