在iOS 7中,苹果增加了一个新的默认导航行为。你可以从屏幕的左边缘滑动回到导航堆栈。但在我的应用程序中,这种行为与我的自定义左侧菜单冲突。那么,是否有可能在UINavigationController中禁用这个新手势?


当前回答

它适用于我的大多数视图控制器。

self.navigationController?.interactivePopGestureRecognizer?.isEnabled = false

对于一些视图控制器,比如UIPageViewController,它并不是无效的。在UIPageViewController的pagecontentviewcontroller下面的代码为我工作。

override func viewDidLoad() {
   self.navigationController?.interactivePopGestureRecognizer?.isEnabled = false
   self.navigationController?.interactivePopGestureRecognizer?.delegate = self
}
override func viewWillDisappear(_ animated: Bool) {
   self.navigationController?.interactivePopGestureRecognizer?.isEnabled = false
   self.navigationController?.interactivePopGestureRecognizer?.delegate = nil
}

On UIGestureRecognizerDelegate,

func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
   if gestureRecognizer == self.navigationController?.interactivePopGestureRecognizer {
      return false
}
      return true
}

其他回答

这适用于viewDidLoad:

  dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
      self.navigationController.interactivePopGestureRecognizer.enabled = false;
  });

在dispatch_after的帮助下,很多问题都可以解决。

尽管请注意,这种解决方案可能不安全,但请使用自己的推理。

更新

对于iOS 8.1,延迟时间应该是0.5秒

在iOS 9.3上不再需要延迟,它只需要将这个放在你的viewDidLoad中: (iOS 9.0-9.3版本待定)

navigationController?.interactivePopGestureRecognizer?.enabled = false

我对Twan的回答做了一些修改,因为:

你的视图控制器可以被设置为其他手势识别器的委托 当你回到根视图控制器并在导航到其他地方之前做一个滑动手势时,将委托设置为nil会导致挂起问题。

下面以iOS 7为例:

{
    id savedGestureRecognizerDelegate;
}

- (void)viewWillAppear:(BOOL)animated
{
    savedGestureRecognizerDelegate = self.navigationController.interactivePopGestureRecognizer.delegate;
    self.navigationController.interactivePopGestureRecognizer.delegate = self;
}

- (void)viewWillDisappear:(BOOL)animated
{
    self.navigationController.interactivePopGestureRecognizer.delegate = savedGestureRecognizerDelegate;
}

- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
{
    if (gestureRecognizer == self.navigationController.interactivePopGestureRecognizer) {
        return NO;
    }
    // add whatever logic you would otherwise have
    return YES;
}

它适用于我的ios 10和更高版本:

- (void)viewWillAppear:(BOOL)animated {
    if ([self.navigationController respondsToSelector:@selector(interactivePopGestureRecognizer)]) {
        self.navigationController.interactivePopGestureRecognizer.enabled = NO;
    }

}

它在viewDidLoad()方法上不起作用。

迅速:

navigationController!.interactivePopGestureRecognizer!.enabled = false

我的方法。一个手势识别器来统治它们:

class DisabledGestureViewController: UIViewController: UIGestureRecognizerDelegate {
    override func viewDidLoad() {
        super.viewDidLoad()
        navigationController!.interactivePopGestureRecognizer!.delegate = self
    }

    func gestureRecognizerShouldBegin(gestureRecognizer: UIGestureRecognizer) -> Bool {
        // Prevent going back to the previous view
        return !(navigationController!.topViewController is DisabledGestureViewController)
    }
}

重要:不要在导航堆栈的任何地方重置委托:navigationController!.interactivePopGestureRecognizer!.delegate = nil