我该如何在SwiftUI中禁用向后滑动手势?子视图只能通过返回按钮来退出。
隐藏导航栏中的返回按钮后,滑动返回手势将被禁用。您可以使用.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()})
}
}
对我而言,添加此扩展程序是有效的(禁用了全局返回手势,以及另一种禁用手势识别器的方法):
extension UINavigationController: UIGestureRecognizerDelegate {
override open func viewDidLoad() {
super.viewDidLoad()
interactivePopGestureRecognizer?.delegate = self
}
public func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
return false
}
}
只有完全删除手势识别器才对我有效。
我将其封装成一个单一的修改器(添加到详细视图)。
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)
}
}
}
UIViewControllerRepresentable
,然后访问其父视图的父视图,无需使用第三方库即可解决导航控制器问题。我使用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
}
}
}
将navigationBarBackButtonHidden
设置为true会失去美丽的动画效果,当你设置了navigationTitle
时。
所以我尝试了另一个答案。
navigationController.interactivePopGestureRecognizer?.isEnabled = false
NavigationLink(destination: CustomView()).introspectNavigationController {navController in
navController.view.gestureRecognizers = []
}
.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)}