Disable Tab View Swipe to Change Page in SwiftUI 2.0
Asked Answered
S

1

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?

Skyla answered 23/6, 2022 at 8:55 Comment(3)
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.Privileged
@Privileged 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 questionSkyla
I do believe you :) but video will not help to debug - if you want help you need to provide your code.Privileged
P
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))
Privileged answered 23/6, 2022 at 9:59 Comment(3)
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 tooSkyla
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())Swinson
This does not work. See issue here: #72962947Aldarcy

© 2022 - 2024 — McMap. All rights reserved.