在 Swift 中禁用滑回手势

我已经在这里找了一段时间但似乎找不到有效的解决办法。

我试图禁用滑动回到以前的视图手势,在迅捷。

我尝试了各种各样的解决方案,包括:

self.navigationController?.interactivePopGestureRecognizer.enabled = false

还有

self.navigationController.interactivePopGestureRecognizer.delegate = self


func gestureRecognizerShouldBegin(gestureRecognizer: UIGestureRecognizer!) -> Bool {
return false
}

有没有一种新的方法可以做到这一点,或者其他一些有效的方法?

82360 次浏览

你可以禁用它,但是不建议这样做,因为大多数 iOS 用户只需要滑动鼠标就可以返回,而按下返回按钮就可以减少返回的次数。 如果你想禁用它,它将是更合理的使用 modal segue而不是推动转移,这是不是一个大的转移。 如果你真的想摆脱滑动回去的功能,我只需要禁用后退按钮,并有一个完成按钮在屏幕右上方。

self.navigationController?.navigationItem.backBarButtonItem?.isEnabled = false;

我可以通过在手势识别程序 ShouldBegin 中返回 false 来实现这一点

class ViewController2: UIViewController, UIGestureRecognizerDelegate {
...
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
self.navigationController?.interactivePopGestureRecognizer.delegate = self
}


func gestureRecognizerShouldBegin(gestureRecognizer: UIGestureRecognizer) -> Bool {
return false
}

Hari 和 Stefan 的回答都没错,但这个更简洁。只要把它放到 viewDidLoad 就行了。

if navigationController!.respondsToSelector(Selector("interactivePopGestureRecognizer")) {
navigationController!.view.removeGestureRecognizer(navigationController!.interactivePopGestureRecognizer)
}

编辑:

一个小小的警告是,如果导航控制器是由另一个视图打开的,而导航控制器是关闭的,那么您将得到一个 EXC _ BAD _ ACCESS 错误。要修复它,您必须保存原始的 UIGestureIdentiizer,并在退出视图时将其放回原处。

声明:

private var popGesture: UIGestureRecognizer?

在取消手势之前:

popGesture = navigationController!.interactivePopGestureRecognizer

然后在关闭视图时:

If popGesture != nil {
navigationController!.view.addGestureRecognizer(popGesture!)
}

以下是禁用和重新启用回扫的简单方法。

Swift 3.x & up

在 viewDidLoad/willAppear/diAppear 方法中添加:

navigationController?.interactivePopGestureRecognizer?.isEnabled = false

请记住,如果使用 viewDidLoad进行此操作,那么下次打开视图时,它可能不会被设置,这取决于它是否保留在堆栈中。

除非你想让它保持关闭状态,否则当视图通过 willMove(toParentViewController:)willDisappear关闭时,你需要重新打开它。你的 navigationController将在 viewDidDisappear为零,所以这是为时已晚。

navigationController?.interactivePopGestureRecognizer?.isEnabled = true

关于 SplitViewController的特别说明:

正如 CompC 在评论中指出的那样,您需要调用第二个导航控制器来将其应用到详细视图:

navigationController?.navigationController?.interactivePopGe‌​stureRecognizer?.isE‌​nabled = false

Swift 2.2 & Objective-C

Swift 2.x 及以下版本:

navigationController?.interactivePopGestureRecognizer?.enabled

目标 C:

self.navigationController.interactivePopGestureRecognizer.enabled

我通常确保在尽可能多的地方启用回滑,甚至添加一个自定义手势识别器来将其添加到模态屏幕。然而,对于我的应用程序中的身份验证和下载过程,我用一个模态导航控制器开始这个过程,然后推动每个下一步的视图。但是,一旦完成,我希望防止它们备份到身份验证屏幕。

对于这个场景,我一直在使用:

navigationController?.interactivePopGestureRecognizer?.isEnabled = false
navigationItem.hidesBackButton = true

viewWillAppear()的最后一个屏幕上。如果在 viewWillDisappear()中推入另一个视图并需要它们,那么可以撤消这些操作。

目标 C

-(void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:true];


self.navigationController.interactivePopGestureRecognizer.enabled = NO;


}

RowanPD 对 Swift 4的逻辑

private var popGesture: UIGestureRecognizer?


override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)


if navigationController!.responds(to: #selector(getter: UINavigationController.interactivePopGestureRecognizer)) {
self.popGesture = navigationController!.interactivePopGestureRecognizer
self.navigationController!.view.removeGestureRecognizer(navigationController!.interactivePopGestureRecognizer!)
}


}


override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)


if let gesture = self.popGesture {
self.navigationController!.view.addGestureRecognizer(gesture)
}


}

如果在你尝试了所有方法之后还是不起作用,那么这就是你错过的东西。

  1. 添加 < code > navationController? . interactivePopGestureIdentiizer? . isEnable = false 到 viewWillAppear (动画:)方法。
  2. 如果不起作用,请从视图控制器中删除导航委托。如果您的视图控制器正在确认 UINavigationControllerDelegateUIGestureRecognizerDelegate协议,请再次进行检查。如果是的话,就移除它。

如果需要在某些屏幕上显示侧面菜单,那么在这个特定的视图上添加 AddScreenEdgePanGesture,而不是导航控制器视图

换掉它

SideMenuManager.default.menuAddScreenEdgePanGesturesToPresent(toView: self.navigationController?.view)

用这个

SideMenuManager.default.menuAddScreenEdgePanGesturesToPresent(toView: self.view)

在将视图控制器推到导航控制器之前添加此行

self.navigationController?.interactivePopGestureRecognizer?.isEnabled = false

而不是

self.navigationController.pushViewController(VC, animated: Bool)

打电话

self.navigationController.setViewContollers([VC], animated: Bool)

所有的风险投资家在堆栈上的 setViewControllers 取代,而不是 增加一个新的控制器在顶部。这意味着新设置的 VC 是根 VC,用户不能回去。

这是最有效的时候,你只想禁用一个风险投资的滑动,并保持其他风险投资的滑动回来。

如果你希望用户能够回去,只是不通过滑动,不要使用这种方法,因为它将禁用所有的回(因为没有 VC 可以回去)。

如果你不关心系统后退按钮的外观(例如,如果你使用自定义后退按钮或导航栏是隐藏的) ,它可能会帮助你:

navigationItem.hidesBackButton = true

它隐藏后退按钮,并禁用滑回手势。

只有 完全删除手势识别器适合我(从目前的视图控制器)。

if let navigationController = parent.navigationController,
let interactivePopGestureRecognizer = navigationController.interactivePopGestureRecognizer {
navigationController.view.removeGestureRecognizer(interactivePopGestureRecognizer)
}

如果您不想返回,或者您设置了新的 rootViewController,请不要使用此选项。

self.navigationController.pushViewController(VC, animated: Bool)

用这个

self.navigationController.setViewContollers([VC], animated: Bool)

删除堆栈上的所有视图控制器,然后用户不能返回。它将禁用所有的返回

有点晚了。在我的情况下 self.navigationController?.navigationItem.backBarButtonItem?.isEnabled = false;不工作。所以我这样做: 您可以呈现视图控制器而不是按视图控制器。这样,滑回手势将不适用于视图控制器。

navigationController?.present(vc, animated: true)

您可以使用解除对您的自定义后退按钮

self.dismiss(animated: true)

注意: 你可以在展示之前设置 VC 模式演示风格,以确保它是全屏的。

vc.modalPresentationStyle = .fullScreen

希望这个能帮上忙。