如何在设置leftBarButtonItem之后在UINavigationController中启用后/左滑动手势?

我从这里得到了相反的问题。 默认情况下,在iOS7UINavigationController的栈的iOS7滑动手势可以popup提供的ViewController 。 现在,我只统一了所有ViewControllersself.navigationItem.leftBarButtonItem样式。

这里是代码:

 self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithImage:LOADIMAGE(@"back_button") style:UIBarButtonItemStylePlain target:self action:@selector(popCurrentViewController)]; 

之后, navigationController.interactivePopGestureRecognizer被禁用。 我怎样才能使stream行手势启用而不删除自定义leftBarButtonItem

谢谢!

首先在viewDidLoad中设置委托:

 self.navigationController.interactivePopGestureRecognizer.delegate = self; 

然后按下时禁用手势:

 - (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated { [super pushViewController:viewController animated:animated]; self.interactivePopGestureRecognizer.enabled = NO; } 

并在viewDidDisappear中启用:

 self.navigationController.interactivePopGestureRecognizer.enabled = YES; 

它适用于我设置委托时

 self.navigationController.interactivePopGestureRecognizer.delegate = self; 

然后执行

 - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldBeRequiredToFailByGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer { return YES; } 

它适合我Swift 3

  func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldBeRequiredToFailBy otherGestureRecognizer: UIGestureRecognizer) -> Bool { return true } 

并在ViewDidLoad中:

  self.navigationController?.interactivePopGestureRecognizer?.delegate = self self.navigationController?.interactivePopGestureRecognizer?.isEnabled = true 

你需要处理两种情况:

  1. 当你将新视图推入堆栈时
  2. 当你显示根视图控制器

如果你只需要一个你可以使用的基类,下面是一个Swift 3版本:

 import UIKit final class SwipeNavigationController: UINavigationController { // MARK: - Lifecycle override init(rootViewController: UIViewController) { super.init(rootViewController: rootViewController) } override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) { super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil) delegate = self } override func viewDidLoad() { super.viewDidLoad() // This needs to be in here, not in init interactivePopGestureRecognizer?.delegate = self } deinit { delegate = nil interactivePopGestureRecognizer?.delegate = nil } // MARK: - Overrides override func pushViewController(_ viewController: UIViewController, animated: Bool) { duringPushAnimation = true super.pushViewController(viewController, animated: animated) } // MARK: - Private Properties fileprivate var duringPushAnimation = false // MARK: - Unsupported Initializers required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } } // MARK: - UINavigationControllerDelegate extension SwipeNavigationController: UINavigationControllerDelegate { func navigationController(_ navigationController: UINavigationController, didShow viewController: UIViewController, animated: Bool) { guard let swipeNavigationController = navigationController as? SwipeNavigationController else { return } swipeNavigationController.duringPushAnimation = false } } // MARK: - UIGestureRecognizerDelegate extension SwipeNavigationController: UIGestureRecognizerDelegate { func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool { guard gestureRecognizer == interactivePopGestureRecognizer else { return true // default value } // Disable pop gesture in two situations: // 1) when the pop animation is in progress // 2) when user swipes quickly a couple of times and animations don't have time to be performed return viewControllers.count > 1 && duringPushAnimation == false } } 

如果您最终需要在另一个类中充当UINavigationControllerDelegate ,则可以编写一个类似于此答案的委托转发器。

从Objective-C的源代码中修改: https : //github.com/fastred/AHKNavigationController

这是在iOS 10中启用/禁用滑动到popup视图控制器的最佳方式,Swift 3

对于第一个屏幕[你想禁用滑动手势]:

 class SignUpViewController : UIViewController,UIGestureRecognizerDelegate { //MARK: - View initializers override func viewDidLoad() { super.viewDidLoad() } override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) swipeToPop() } override func viewWillDisappear(_ animated: Bool) { super.viewWillDisappear(animated) } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() } func swipeToPop() { self.navigationController?.interactivePopGestureRecognizer?.isEnabled = true; self.navigationController?.interactivePopGestureRecognizer?.delegate = self; } func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool { if gestureRecognizer == self.navigationController?.interactivePopGestureRecognizer { return false } return true } } 

对于中间屏幕[您想要启用滑动手势的位置]:

 class FriendListViewController : UIViewController { //MARK: - View initializers override func viewDidLoad() { super.viewDidLoad() swipeToPop() } func swipeToPop() { self.navigationController?.interactivePopGestureRecognizer?.isEnabled = true; self.navigationController?.interactivePopGestureRecognizer?.delegate = nil; } } 

设置自定义后退button将禁用向后滑动function。

保留它的最好的办法是UINavigationViewController并将其自身设置为interactivePopGestureRecognizer委托; 那么您可以从gestureRecognizerShouldBegin返回YES以允许向后滑动。

例如,这是在AHKNavigationController中完成的

和一个Swift版本在这里: https : //stackoverflow.com/a/43433530/308315

Swift 3:

 override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) self.navigationController?.interactivePopGestureRecognizer?.delegate = self } func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool { return true } func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRequireFailureOf otherGestureRecognizer: UIGestureRecognizer) -> Bool { return (otherGestureRecognizer is UIScreenEdgePanGestureRecognizer) } 

对于那些仍然有这个问题的人,请尝试分离两行如下。

 override func viewDidLoad() { self.navigationController!.interactivePopGestureRecognizer!.delegate = self ... override func viewWillAppear(_ animated: Bool) { self.navigationController!.interactivePopGestureRecognizer!.isEnabled = true ... 

显然,在我的应用程序中,

interactivePopGestureRecognizer!.isEnabled

在出于某种原因显示视图之前重置为false