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


当前回答

我发现只把手势设置为禁用并不总是有效。它确实有用,但对我来说,只有在我用过一次后才起作用。第二次就不会触发手势了。

修复我是委托手势和实现shouldbegin方法返回NO:

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

    // Disable iOS 7 back gesture
    if ([self.navigationController respondsToSelector:@selector(interactivePopGestureRecognizer)]) {
        self.navigationController.interactivePopGestureRecognizer.enabled = NO;
        self.navigationController.interactivePopGestureRecognizer.delegate = self;
    }
}

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

    // Enable iOS 7 back gesture
    if ([self.navigationController respondsToSelector:@selector(interactivePopGestureRecognizer)]) {
        self.navigationController.interactivePopGestureRecognizer.enabled = YES;
        self.navigationController.interactivePopGestureRecognizer.delegate = nil;
    }
}

- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
{
    return NO;
}

其他回答

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

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

我找到了一个解决方案:

objective - c:

if ([self.navigationController respondsToSelector:@selector(interactivePopGestureRecognizer)]) {
    self.navigationController.interactivePopGestureRecognizer.enabled = NO;
}

斯威夫特3 +: self.navigationController?.interactivePopGestureRecognizer?.isEnabled = false

迅速:

navigationController!.interactivePopGestureRecognizer!.enabled = false

Swift 5、Swift 4.2可以使用下面的代码。

// disable
self.navigationController?.interactivePopGestureRecognizer?.isEnabled = false
// enable
self.navigationController?.interactivePopGestureRecognizer?.isEnabled = true

所有这些解决方案都以一种他们不推荐的方式操纵苹果的手势识别器。我的一个朋友刚刚告诉我,有一个更好的解决方案:

[navigationController.interactivePopGestureRecognizer requireGestureRecognizerToFail: myPanGestureRecognizer];

其中myPanGestureRecognizer是你用来显示菜单的手势识别器。这样,当你按下一个新的导航控制器时,苹果的手势识别器就不会被重新打开,也不需要依赖黑客延迟,如果你的手机处于睡眠状态或负载过重,可能会过早触发。

把这个留在这里,因为我知道下次需要的时候我不会记得了,然后我就有了这个问题的解决方案。