【问题标题】:Disable swipe-back for a NavigationLink SwiftUI禁用 NavigationLink SwiftUI 的回扫
【发布时间】:2020-04-13 17:41:01
【问题描述】:

如何禁用 SwiftUI 中的向后滑动手势?子视图只能通过后退按钮关闭。

【问题讨论】:

    标签: swiftui


    【解决方案1】:

    只有完全移除手势识别器对我有用。
    我将它包装成一个修饰符(要添加到详细视图中)。

    struct ContentView: View {
        
        var body: some View {
            VStack {
                ...
            )
            .disableSwipeBack()
        }
    }
    

    DisableSwipeBack.swift

    import Foundation
    import SwiftUI
    
    extension View {
        func disableSwipeBack() -> some View {
            self.background(
                DisableSwipeBackView()
            )
        }
    }
    
    struct DisableSwipeBackView: UIViewControllerRepresentable {
        
        typealias UIViewControllerType = DisableSwipeBackViewController
        
        
        func makeUIViewController(context: Context) -> UIViewControllerType {
            UIViewControllerType()
        }
        
        func updateUIViewController(_ uiViewController: UIViewControllerType, context: Context) {
        }
    }
    
    class DisableSwipeBackViewController: UIViewController {
        
        override func didMove(toParent parent: UIViewController?) {
            super.didMove(toParent: parent)
            if let parent = parent?.parent,
               let navigationController = parent.navigationController,
               let interactivePopGestureRecognizer = navigationController.interactivePopGestureRecognizer {
                navigationController.view.removeGestureRecognizer(interactivePopGestureRecognizer)
            }
        }
    }
    

    您可以通过在 SwiftUI 层次结构中使用 UIViewControllerRepresentable 来解析导航控制器而无需第三方,然后访问其父级的父级。

    【讨论】:

      【解决方案2】:

      navigationBarBackButtonHidden设置为true会在设置navigationTitle时失去漂亮的动画。

      所以我尝试了另一个答案

      navigationController.interactivePopGestureRecognizer?.isEnabled = false
      

      但这对我不起作用。

      尝试以下代码后运行正常

      NavigationLink(destination: CustomView()).introspectNavigationController {navController in
                  navController.view.gestureRecognizers = []
              }
      

      preview

      【讨论】:

      • 这应该被标记为正确答案。正如你所说,其他那些你最终会失去漂亮的 iOS 动画。
      【解决方案3】:

      我使用 Introspect 库然后我就这样做了:

      import SwiftUI
      import Introspect
      
      struct ContentView: View {
         var body: some View {
            Text("A view that cannot be swiped back")
                 .introspectNavigationController { navigationController in
                    navigationController.interactivePopGestureRecognizer?.isEnabled = false
            }
         }
      }
      

      【讨论】:

        【解决方案4】:

        以下更多复制了现有的 iOS 人字形图像。 对于接受的答案。 即用图像 chevron 替换 "back"

         .navigationBarItems(leading: Button("Back"){self.presentationMode.wrappedValue.dismiss()})
        

        Button(action: {self.presentationMode.wrappedValue.dismiss()}){Image(systemName: "chevron.left").foregroundColor(Color.blue).font(Font.system(size:23, design: .serif)).padding(.leading,-6)}
        

        【讨论】:

          【解决方案5】:

          This answer 展示了如何在 SwiftUI 中配置导航控制器(简而言之,使用 UIViewControllerRepresentable 访问 UINavigationController)。 this answer 展示了如何禁用滑动手势。将它们结合起来,我们可以执行以下操作:

          Text("Hello")
            .background(NavigationConfigurator { nc in
               nc.interactivePopGestureRecognizer?.isEnabled = false
            })
          

          这样您就可以继续使用内置的后退按钮功能。

          【讨论】:

            【解决方案6】:

            通过隐藏导航栏中的后退按钮,可以禁用向后滑动手势。您可以使用.navigationBarItems() 设置自定义后退按钮

            struct ContentView: View {
                var body: some View {
                    NavigationView{
                        List{
                            NavigationLink(destination: Text("You can swipe back")){
                                Text("Child 1")
                            }
                            NavigationLink(destination: ChildView()){
                                Text("Child 2")
                            }
                        }
                    }
                }
            }
            
            struct ChildView: View{
                @Environment(\.presentationMode) var presentationMode
            
                var body:some View{
                    Text("You cannot swipe back")
                        .navigationBarBackButtonHidden(true)
                        .navigationBarItems(leading: Button("Back"){self.presentationMode.wrappedValue.dismiss()})
                }
            }
            
            

            【讨论】:

            • 这可行,但至少会让您失去您可能关心或不关心的后退按钮的本地化(即国际化)。
            • 有没有办法隐藏后退按钮而不会失去滑动返回?
            猜你喜欢
            • 1970-01-01
            • 2020-04-27
            • 2020-04-16
            • 2020-10-04
            • 2019-11-23
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2020-04-11
            相关资源
            最近更新 更多