隐藏NavigationBarBackButton时,实现右滑关闭页面
引言:现在的大多数iOS App都有右滑关闭页面的功能,众多iPhone用户也都习惯了这种操作
当使用系统自带的NavigationBarBackButton时可以很轻松实现这个功能,但系统自带的BackButton通常会带上个页面的Title,并且需求通常需要自定义NavigationBar,就需要隐藏系统自带的返回摁钮,这时右滑返回的功能也消失了,这非常头疼
1.先看使用系统返回摁钮时操作
代码:
swift
import SwiftUI
//父页面
struct IndexView: View {
var body: some View {
NavigationView{
VStack {
NavigationLink {
ChildView()
} label: {
Text("jump to ChileView")
}
}
.navigationBarTitle("首页", displayMode: .inline)
}
}
}
//子页面
struct ChildView: View {
var body: some View {
VStack {
Text("ChildView")
}
.navigationBarTitle("子页面", displayMode: .inline)
}
}
ps:可以发现子页面的返回摁钮会显示父页面的title,这通常是不符合页面UI的需求,但此时是可以满足右滑跳转的
2.当隐藏掉返回Button时操作
代码:
swift
import SwiftUI
//父页面
struct IndexView: View {
var body: some View {
NavigationView{
VStack {
NavigationLink {
ChildView()
} label: {
Text("jump to ChileView")
}
}
.navigationBarTitle("首页", displayMode: .inline)
}
}
}
//子页面
struct ChildView: View {
@Environment(\.presentationMode) var presentionation //点了确定后 让本页面关闭消失的变量
var body: some View {
VStack {
Text("ChildView")
}
.navigationBarTitle("子页面", displayMode: .inline)
.navigationBarBackButtonHidden(true)
.navigationBarItems(
leading:
Button(action: {
self.presentionation.wrappedValue.dismiss()
}, label: {
Image(systemName: "chevron.left")
.foregroundColor(Color.black)
})
)
}
}
ps:这时我们可以满足UI的需求和设计,但是右滑返回的功能跟着BackButton一起隐藏掉了,这时功能就出现了缺失
3.这时候只需要给UINavigationController添加额外的代理和方法即可实现
新增代理代码:
swift
import SwiftUI
//右滑返回
extension UINavigationController: UIGestureRecognizerDelegate {
override open func viewDidLoad() {
super.viewDidLoad()
interactivePopGestureRecognizer?.delegate = self
}
public func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
return viewControllers.count > 1
}
}
原代码不变:
swift
import SwiftUI
//父页面
struct IndexView: View {
var body: some View {
NavigationView{
VStack {
NavigationLink {
ChildView()
} label: {
Text("jump to ChileView")
}
}
.navigationBarTitle("首页", displayMode: .inline)
}
}
}
//子页面
struct ChildView: View {
@Environment(\.presentationMode) var presentionation //点了确定后 让本页面关闭消失的变量
var body: some View {
VStack {
Text("ChildView")
}
.navigationBarTitle("子页面", displayMode: .inline)
.navigationBarBackButtonHidden(true)
.navigationBarItems(
leading:
Button(action: {
self.presentionation.wrappedValue.dismiss()
}, label: {
Image(systemName: "chevron.left")
.foregroundColor(Color.black)
})
)
}
}