简体   繁体   English

在 Swift 中禁用向后滑动手势

[英]Disable swipe back gesture in Swift

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 中禁用滑动到 go 回到上一个视图手势。

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?有没有新的方法可以做到这一点或其他一些有效的方法?

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 .除非您希望它保持关闭状态,否则您需要在通过willMove(toParentViewController:)willDisappear关闭视图时将其重新打开。 Your navigationController will be nil at viewDidDisappear , so that is too late.您的navigationControllerviewDidDisappear将为零,所以为时已晚。

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

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.您可以禁用它,但不建议这样做,因为大多数 iOS 用户通过滑动返回,按下返回按钮则更少。 If you want to disable it it would be more reasonable to use a modal segue instead of a push segue which is not that big of a transfer.如果你想禁用它,使用modal segue而不是推送转场会更合理,因为推送转场不是那么大。 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.如果你真的想摆脱滑动返回功能,我只会禁用后退按钮并在屏幕右上角有一个完成按钮。

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

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
}

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

self.navigationController?.interactivePopGestureRecognizer?.isEnabled = false

Nothing wrong with either answer from Hari or Stefan but this is more succinct. Hari 或 Stefan 的回答都没有错,但这更简洁。 Just put it in viewDidLoad and you're done.只需将其放入 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.一个小小的警告是,如果 Navigation Controller 被另一个视图打开并且 Navigation Controller 关闭,那么您将收到 EXC_BAD_ACCESS 错误。 To fix it you have to save the original UIGestureRecognizer and put it back when you exit the view.要修复它,您必须保存原始 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!)
}

for objective -c对于目标 -c

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

  self.navigationController.interactivePopGestureRecognizer.enabled = NO;

}

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.在最终屏幕上的viewWillAppear() You can undo these in viewWillDisappear() if you're pushing another view and need them there.如果您正在推送另一个视图并在那里需要它们,您可以在viewWillDisappear()撤消这些。

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

}

Instead of代替

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

call称呼

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

setViewControllers replaces the all the VCs on the stack, instead of adding a new controller on top. setViewControllers替换堆栈上的所有 VC,而不是在顶部添加新控制器。 This means that the new set VC is the root VC, and the user cannot go back.这意味着新设置的 VC 是根 VC,用户无法返回。

This is most effective when you only want to disable the swipe on a single VC, and keep the swipe-to-back for the other VC.当您只想在单个 VC 上禁用滑动并为另一个 VC 保持滑动到背面时,这是最有效的。

If you want users to be able to go back, just not through swiping, do not use this method as it will disable all backs (as there is no VC to go back to).如果您希望用户能够返回,而不是通过滑动,请不要使用此方法,因为它会禁用所有返回(因为没有可返回的 VC)。

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.navigationController?.interactivePopGestureRecognizer?.isEnabled = false到您的 viewWillAppear(animated:) 方法。
  2. if it doesn't work, remove navigation delegate from the view controller.如果它不起作用,请从视图控制器中删除导航委托。 Check again if your view controller is confirming UINavigationControllerDelegate , UIGestureRecognizerDelegate protocols.再次检查您的视图控制器是否正在确认UINavigationControllerDelegateUIGestureRecognizerDelegate协议。 if so, just remove it.如果是这样,只需将其删除。

Come here a little bit late.来这里有点晚了。 In my case self.navigationController?.navigationItem.backBarButtonItem?.isEnabled = false;在我的例子self.navigationController?.navigationItem.backBarButtonItem?.isEnabled = false; not working.不工作。 So I do this: you can present view controller instead of push view controller. This way the swipe back gesture will not apply to the view controller.所以我这样做:您可以呈现视图 controller 而不是推送视图 controller。这样,向后滑动手势将不适用于视图 controller。

navigationController?.present(vc, animated: true)

You could use dismiss for your custom back button您可以为自定义后退按钮使用 dismiss

self.dismiss(animated: true)

Note: You could set VC modal presentation style before present it to make sure it's full screen.注意:您可以在呈现它之前设置 VC 模态呈现样式以确保它是全屏的。

vc.modalPresentationStyle = .fullScreen

Hope this help.希望这有帮助。

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)

If you don't care about system back button appearance (for example, if you're using custom back button or navigation bar is hidden at all), it might help you:如果您不关心系统后退按钮的外观(例如,如果您使用自定义后退按钮或导航栏完全隐藏),它可能会帮助您:

navigationItem.hidesBackButton = true

It hides back button and disables swipe back gesture.它隐藏后退按钮并禁用向后滑动手势。

Only complete removal of the gesture recognizer worked for me (from the presenting view controller).只有完全删除手势识别器才对我有用(从呈现视图控制器)。

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

Don't Use this if you don't want to come back, or you set the new rootViewController.如果你不想回来,或者你设置了新的 rootViewController,请不要使用它。

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

Use this用这个

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

setViewControllers Remove all the View Controllers on the stack then the user cannot go back. setViewControllers 删除堆栈上的所有视图控制器,然后用户无法返回 go。 it will disable all backs它将禁用所有后背

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM