ios 在 Swift 中禁用向后滑动手势

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/31731751/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 07:04:04  来源:igfitidea点击:

Disable swipe back gesture in Swift

iosswiftuinavigationcontroller

提问by Phil Hudson

Been looking around on here for a while but can't seem to find a working solution.

在这里环顾了一段时间,但似乎找不到可行的解决方案。

I'm trying to disable the swipe to go back to previous view gesture, in Swift.

我正在尝试在 Swift 中禁用滑动以返回上一个视图手势。

I've tried a variety of solutions including:

我尝试了多种解决方案,包括:

self.navigationController?.interactivePopGestureRecognizer.enabled = false

and

self.navigationController.interactivePopGestureRecognizer.delegate = self

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

Is there a new method of doing this or some other method that works?

是否有一种新的方法可以做到这一点或其他一些有效的方法?

采纳答案by Stefan DeClerck

You could disable it but that would not be to recommended as most iOS users go back by swiping and less by pressing the back button. If you want to disable it it would be more reasonable to use a modal segueinstead of a push segue which is not that big of a transfer. If you really want to get rid of the swipe to go back function I would just disable the back button and have a done button on the top right of the screen.

您可以禁用它,但不建议这样做,因为大多数 iOS 用户通过滑动返回,按下返回按钮则更少。如果你想禁用它,使用 amodal segue而不是 push segue会更合理,因为它不是那么大的传输。如果你真的想摆脱滑动返回功能,我只会禁用后退按钮并在屏幕右上角有一个完成按钮。

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

回答by CodeBender

The following is an easy approach to disabling & re-enabling the swipe back.

以下是禁用和重新启用向后滑动的简单方法。

Swift 3.x & up

Swift 3.x 及更高版本

In a viewDidLoad/willAppear/didAppear method add:

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

navigationController?.interactivePopGestureRecognizer?.isEnabled = false

Just keep in mind that if you do it with viewDidLoad, then the next time you open the view, it may not be set depending upon whether or not it remains in your stack.

请记住,如果您使用viewDidLoad,那么下次打开视图时,可能不会设置它,具体取决于它是否保留在您的堆栈中。

Unless you want it to remain off, you will need to turn it back on when the view is closed via either willMove(toParentViewController:)or willDisappear. Your navigationControllerwill be nil at viewDidDisappear, so that is too late.

除非您希望它保持关闭状态,否则您需要在通过willMove(toParentViewController:)或关闭视图时将其重新打开willDisappear。您navigationController将在 处为零viewDidDisappear,所以为时已晚。

navigationController?.interactivePopGestureRecognizer?.isEnabled = true

A special note on SplitViewControllers:

关于SplitViewControllers的特别说明:

As pointed out by CompC in the comments, you will need to call the second navigation controller to apply it to a detail view as such:

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

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

Swift 2.2 & Objective-C

Swift 2.2 和 Objective-C

Swift versions 2.x & below:

Swift 2.x 及以下版本:

navigationController?.interactivePopGestureRecognizer?.enabled

Objective-C:

目标-C:

self.navigationController.interactivePopGestureRecognizer.enabled

回答by Hari Kunwar

I was able to do this by returning false in gestureRecognizerShouldBegin

我能够通过在gestureRecognizerShouldBegin中返回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
}

回答by RowanPD

Nothing wrong with either answer from Hari or Stefan but this is more succinct. Just put it in viewDidLoad and you're done.

Hari 或 Stefan 的回答都没有错,但这更简洁。只需将其放入 viewDidLoad 即可完成。

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

EDIT:

编辑:

One small caveat is that if the Navigation Controller was opened by another view and the Navigation Controller is closed then you'll get an EXC_BAD_ACCESS error. To fix it you have to save the original UIGestureRecognizer and put it back when you exit the view.

一个小小的警告是,如果 Navigation Controller 被另一个视图打开并且 Navigation Controller 关闭,那么您将收到 EXC_BAD_ACCESS 错误。要修复它,您必须保存原始 UIGestureRecognizer 并在退出视图时将其放回原处。

Declare:

宣布:

private var popGesture: UIGestureRecognizer?

Immediately before removing the gesture:

在移除手势之前:

popGesture = navigationController!.interactivePopGestureRecognizer

Then when closing the view:

然后在关闭视图时:

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

回答by Maulik Patel

for objective -c

对于目标 -c

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

  self.navigationController.interactivePopGestureRecognizer.enabled = NO;

}

回答by David Seek

RowanPD's logic for Swift 4

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)
    }

}

回答by blwinters

I generally make sure that swipe back is enabled in as many places as possible, even adding a custom gesture recognizer to add it to modal screens. However for an authentication and download process in my app I start the process with a modal navigation controller and then push the view for each next step. However, once it's completed I want to prevent them from backing up into the authentication screens.

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

For this scenario I've been using:

对于这种情况,我一直在使用:

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

in viewWillAppear()on the final screen. You can undo these in viewWillDisappear()if you're pushing another view and need them there.

viewWillAppear()最后的屏幕上。viewWillDisappear()如果您正在推送另一个视图并在那里需要它们,您可以撤消这些。

回答by Li Jin

This is something you missed if it doesn't work after you tried all.

如果在您尝试了所有方法后它不起作用,那么您就错过了这一点。

  1. Add navigationController?.interactivePopGestureRecognizer?.isEnabled = false to your viewWillAppear(animated:) method.
  2. if it doesn't work, remove navigation delegate from the view controller. Check again if your view controller is confirming UINavigationControllerDelegate, UIGestureRecognizerDelegateprotocols. if so, just remove it.
  1. 添加navigationController?.interactivePopGestureRecognizer?.isEnabled = false 到您的 viewWillAppear(animated:) 方法。
  2. 如果它不起作用,请从视图控制器中删除导航委托。再次检查,如果您的视图控制器确认UINavigationControllerDelegateUIGestureRecognizerDelegate协议。如果是这样,只需将其删除。

回答by Spydy

If requirement is to show side menu on some of the screens then add AddScreenEdgePanGesture on this specific view instead of navigationController view

如果需要在某些屏幕上显示侧边菜单,则在此特定视图上添加 AddScreenEdgePanGesture 而不是 navigationController 视图

replace it

代替它

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

with this

有了这个

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

回答by Behnam Rakhshani

Add this line before pushing view controller to navigation controller

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

self.navigationController?.interactivePopGestureRecognizer?.isEnabled = false