在SwiftUI中隐藏导航栏而不丢失回扫手势

在SwiftUI中隐藏导航栏而不丢失回扫手势,swift,swiftui,Swift,Swiftui,在SwiftUI中,每当导航栏被隐藏时,滑动返回手势也会被禁用 有没有办法隐藏导航栏,同时在SwiftUI中保留回扫手势?我已经有了一个自定义的“后退”按钮,但仍然需要这个手势 我见过一些UIKit的解决方案,但仍然不知道如何在SwiftUI中实现 以下是您自己尝试的代码: import SwiftUI struct RootView: View { var body: some View { NavigationView { Navigatio

在SwiftUI中,每当导航栏被隐藏时,滑动返回手势也会被禁用

有没有办法隐藏导航栏,同时在SwiftUI中保留回扫手势?我已经有了一个自定义的“后退”按钮,但仍然需要这个手势

我见过一些UIKit的解决方案,但仍然不知道如何在SwiftUI中实现

以下是您自己尝试的代码:

import SwiftUI

struct RootView: View {
    var body: some View {
        NavigationView {
            NavigationLink(destination: SecondView()) {
                Text("Go to second view")
            }
        }
    }
}

struct SecondView: View {
    var body: some View{
        Text("As you can see, swipe to go back will not work")
        .navigationBarTitle("")
        .navigationBarHidden(true)
    }
}

非常感谢您的任何建议或解决方案

我查阅了有关此问题的文档和其他来源,但未发现任何内容。基于使用
UIKit
UIViewControllerRepresentable
的解决方案很少。我尝试组合解决方案,甚至在用其他视图替换“后退”按钮时也保存了“向后滑动”手势。代码仍然有点脏,但我认为这是进一步研究的起点(例如完全隐藏导航栏)。下面是
ContentView
的样子:

导入快捷界面
结构ContentView:View{
var body:一些观点{
Swipeback导航控制器{
SwipeBackNavigationLink(目标:DetailViewWithCustomBackButton()){
文本(“主视图”)
}
.navigationBarTitle(“标准SwiftUI导航视图”)
}
.edgesIgnoringSafeArea(.top)
}
}
//标记:带有自定义后退按钮的局部视图
带有CustomBackButton的结构详细视图:视图{
@环境(\.presentationMode)变量presentationMode
var body:一些观点{
文本(“细节”)
.navigationBarItems(前导:按钮(操作:{
self.dismissView()
}) {
HStack{
图像(系统名称:“返回”)
文本(“背面”)
}
})
.navigationBarTitle(“详细视图”)
}
私有函数dismissView(){
presentationMode.wrappedValue.Disclease()
}
}
下面是模拟
NavigationView
NavigationLink
swipebacknavigationcontroller
NavigationLink
的实现。它们只是
SwipeNavigationController
工作的包装。最后一个是
UINavigationController
的子类,可以根据您的需要进行自定义:

导入UIKit
导入快捷键
结构SwipeBackNavController:UIViewControllerRepresentable{
让内容:内容
public init(@ViewBuilder内容:@escaping()->content){
self.content=content()
}
func makeUIViewController(上下文:context)->SwipeNavigationController{
让hostingController=UIHostingController(rootView:content)
设swipeBackNavController=SwipeNavigationController(rootViewController:hostingController)
返回swipeBackNavController
}
func updateUIViewController(uuPageViewController:SwipeNavigationController,上下文:上下文){
}
}
结构SwipeBackNavigationLink:视图{
var目的地:目的地
变量标签:()->标签
公共初始化(目标:目标,@ViewBuilder标签:@escaping()->label){
self.destination=目的地
self.label=标签
}
var body:一些观点{
按钮(操作:{
guard let window=UIApplication.shared.windows.first else{return}
guard let swipeBackNavController=window.rootViewController?.children.first作为?SwipeNavigationController else{return}
swipeBackNavController.pushSwipeBackView(DetailViewWithCustomBackButton())
},标签:label)
}
}
最后一类SwipeNavigationController:UINavigationController{
//马克:生命周期
重写初始化(rootViewController:UIViewController){
super.init(rootViewController:rootViewController)
}
重写init(nibName-nibNameOrNil:String?,bundle-nibBundleOrNil:bundle?){
super.init(nibName:nibNameOrNil,bundle:nibBundleOrNil)
代表=自我
}
必需的初始化?(编码器aDecoder:NSCoder){
super.init(编码者:aDecoder)
代表=自我
}
重写func viewDidLoad(){
super.viewDidLoad()
//这需要在这里,而不是在init中
InteractivePostureRecognizer?.delegate=self
}
脱硝{
委托=零
InteractivePostureRecognitor?.delegate=nil
}
//标记:-覆盖
覆盖func pushViewController(viewController:UIViewController,动画:Bool){
duringPushAnimation=true
setNavigationBarHidden(真,动画:假)
super.pushViewController(viewController,动画:动画)
}
var duringPushAnimation=false
//标记:-自定义函数
func pushSwipeBackView(u内容:内容),其中内容:视图{
让hostingController=SwipeBackHostingController(rootView:content)
self.delegate=hostingController
self.pushViewController(hostingController,动画:true)
}
}
//标记:-UINavigationControllerDelegate
扩展开关激活控制器:UINavigationControllerDelegate{
func navigationController(navigationController:UINavigationController,didShow viewController:UIViewController,动画:Bool){
guard let swipeNavigationController=navigationController as?swipeNavigationController else{return}
swipeNavigationController.duringPushAnimation=false
}
}
//MARK:-UIgestureRecognitizerDelegate
扩展开关激活控制器:UIgestureRecognitizerDelegate{
func gestureRecognizer应该开始(uGestureRecognizer:UIGestureRecognizer)->Bool{
guard gestureRecognizer==InteractiveEPopGetureRecognizer else{
返回true//默认值
}
//在两种情况下禁用弹出手势:
//1)当pop动画正在进行时
//2)当用户快速滑动几次并且动画没有时间执行时
让结果=viewContro
extension View {
    public func currentDeviceNavigationViewStyle() -> AnyView {
        if UIDevice.current.userInterfaceIdiom == .pad {
            return AnyView(self.navigationViewStyle(DefaultNavigationViewStyle()))
        } else {
            return AnyView(self.navigationViewStyle(StackNavigationViewStyle()))
        }
    }
}