在 SwifUI TabView 中禁用滑动手势

Posted

技术标签:

【中文标题】在 SwifUI TabView 中禁用滑动手势【英文标题】:Disable Swipe Gesture in SwifUI TabView 【发布时间】:2021-03-03 04:23:30 【问题描述】:

尝试在SwiftUI 中实现TabViewPageTabView 样式,其中导航仅以编程方式完成,并且所有滑动手势均被禁用。

This solution 仅部分起作用 - 如果您在选择更改时点击屏幕,它仍然会干扰过渡并导致奇怪的效果。此外,如果您用两根手指滚动,手势仍会注册。我需要一个完全禁用滑动手势的解决方案。

代码:

struct PageViewTest: View 
    @State var selection: Int = 1
    
    var body: some View 
        ZStack 
            Color.green.ignoresSafeArea()
            
            TabView(selection: $selection) 
                Color.red
                    .tag(1)
                    .gesture(DragGesture())
                
                Color.blue
                    .tag(2)
                    .gesture(DragGesture())
                
                Color.yellow
                    .tag(3)
                    .gesture(DragGesture())
            
            .tabViewStyle(PageTabViewStyle(indexDisplayMode: .never))
            .animation(.linear, value: selection)
            
            VStack 
                Spacer()
                Button(action: 
                    selection = selection == 3 ? 1 : selection + 1
                ) 
                    Text("next")
                        .foregroundColor(.white)
                        .font(.title)
                
            
        
    

.disabled(true) 设置为TabView 可以解决此问题,但随后所有子视图都不再具有交互性。

【问题讨论】:

如果您不想在 TabView 上滑动手势,为什么要为每个手势提供 DragGesture()DragGesture() 是什么?有什么代码吗? DragGesture() 将一个空手势(什么都不做)附加到该视图,我假设它会覆盖默认的拖动行为。 我测试了你的代码,标签没有滑动,所以你想要的已经在那里了!我错过了什么? 尝试用两根手指滚动 我想我可以帮助你,但我需要知道不使用 TabView 会解决什么问题,但你也可以像以前一样更改 App 页面? 【参考方案1】:

This answer 允许在 SwiftUI 中使用自定义手势识别器创建叠加层。 然后我们只需要创建一个不允许手势启动的委托。

所以代码是:

import SwiftUI
import UIKit


struct ContentView: View 
    @State var selection: Int = 1
    let numTabs = 3
    let minDragTranslationForSwipe: CGFloat = 5000

    var body: some View 
        ZStack 
            Color.green.ignoresSafeArea()
            
            TabView(selection: $selection) 
                Color.red
                    .tag(1)
                Color.blue
                    .tag(2)
                Color.yellow
                    .tag(3)
            
            .tabViewStyle(PageTabViewStyle(indexDisplayMode: .never))
            .animation(.linear, value: selection)
                .overlay(TouchesHandler())
            
            VStack 
                Spacer()
                Button(action: 
                    selection = selection == 3 ? 1 : selection + 1
                ) 
                    Text("next")
                        .foregroundColor(.white)
                        .font(.title)
                
            
        

    


//just a dummy
class MySwipeGesture: UISwipeGestureRecognizer 

    @objc func noop() 

    init(target: Any?) 
        super.init(target: target, action: #selector(noop))
    


//this delegate effectively disables the gesure
class MySwipeGestureDelegate: NSObject, UIGestureRecognizerDelegate 
    func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool 
        false
    


//and the overlay inspired by the answer from the link above
struct TouchesHandler: UIViewRepresentable 

    func makeUIView(context: UIViewRepresentableContext<TouchesHandler>) -> UIView 
        let view = UIView(frame: .zero)
        view.isUserInteractionEnabled = true
        view.addGestureRecognizer(context.coordinator.makeGesture())
        return view;
    

    func updateUIView(_ uiView: UIView, context: UIViewRepresentableContext<TouchesHandler>) 
    

    func makeCoordinator() -> Coordinator 
        return Coordinator()
    

    class Coordinator 
        var delegate: UIGestureRecognizerDelegate = MySwipeGestureDelegate()
        func makeGesture() -> MySwipeGesture 
            delegate = MySwipeGestureDelegate()
            let gr = MySwipeGesture(target: self)
            gr.delegate = delegate
            return gr
        
    
    typealias UIViewType = UIView

【讨论】:

以上是关于在 SwifUI TabView 中禁用滑动手势的主要内容,如果未能解决你的问题,请参考以下文章

在 Swift 中禁用向后滑动手势

禁用 iCarousel 的滑动手势

REFrostedViewController 平移手势禁用 tableview 滑动

如何在 ios 11 中使用主详细信息视图禁用向后滑动手势?

如何在 iOS 7 上的 UINavigationController 中禁用向后滑动手势

如何禁用 UITableView 上的左右滑动手势