如何在iOS 7上的UINavigationController中禁用后滑动手势

Art*_*eel 320 objective-c uinavigationcontroller uigesturerecognizer ios ios7

在iOS 7中,Apple添加了一个新的默认导航行为.您可以从屏幕的左边缘滑动以返回导航堆栈.但在我的应用程序中,此行为与我的自定义左菜单冲突.那么,是否可以在UINavigationController中禁用这个新手势?

Art*_*eel 578

我找到了解决方案:

Objective-C的:

if ([self.navigationController respondsToSelector:@selector(interactivePopGestureRecognizer)]) {
    self.navigationController.interactivePopGestureRecognizer.enabled = NO;
}
Run Code Online (Sandbox Code Playgroud)

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

  • 当然,如果您支持旧版本的iOS,则需要检查新方法的可用性. (28认同)
  • 在iOS8上,设置`self.navigationController.interactivePopGestureRecognizer.enabled`属性在以下视图的方法中不起作用:`viewDidLoad`,`viewWillAppear`,`viewDidAppear`,`viewDidDisappear`,但在方法`viewWillDisappear`中有效.在iOS7上,它适用于上述所有方法.所以在使用viewController时尝试在任何其他方法中使用它,我确认它在iOS8上对我有用,当我点击视图内的一些按钮时. (25认同)
  • 你可以在`viewDidAppear:`/`viewDidDisappear`上'启用/禁用'识别器.或者,您可以使用更复杂的逻辑实现`UIGestureRecognizerDelegate`协议,并将其设置为`recognizer.delegate`属性. (11认同)
  • 可以确认这在iOS8中的viewDidLoad和viewWillAppear中不起作用,将其放入viewwilllayoutgubviews中就可以了 (8认同)
  • 我相信这在iOS 8中不再适用 (6认同)
  • 有没有办法禁用它的视图药水? (2认同)

Ant*_*ine 46

我发现将手势设置为禁用只是并不总是有效.它确实有效,但对我而言,它只是在我曾经使用过背景后才做到的.第二次它不会触发反馈.

修复我的是委托手势并实现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;
}
Run Code Online (Sandbox Code Playgroud)


Vla*_*lov 29

只需从NavigationController中删除手势识别器.在iOS 8中工作.

if ([self.navigationController respondsToSelector:@selector(interactivePopGestureRecognizer)])
    [self.navigationController.view removeGestureRecognizer:self.navigationController.interactivePopGestureRecognizer];
Run Code Online (Sandbox Code Playgroud)

  • 也适用于iOS 10,这应该是公认的答案.顺便说一句,如果你想重新启用它,请在某处执行`[self.navigationController.view addGestureRecognizer:self.navigationController.interactivePopGestureRecognizer]. (7认同)

Cha*_*man 22

从iOS 8开始,接受的答案不再适用.我需要停止在我的主游戏屏幕上解除手势,所以实现了这个:

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

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

- (void)viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];
    if ([self.navigationController respondsToSelector:@selector(interactivePopGestureRecognizer)]) {
    self.navigationController.interactivePopGestureRecognizer.delegate = nil;
    }

}

- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
{
     return NO;
}
Run Code Online (Sandbox Code Playgroud)

  • 虽然这适用于iOS8,我会在行上发出警告*.delegate = self; 声明:从不兼容类型'ViewController*const __strong'分配给id <UIGestureRecognizerDelegate>' (2认同)
  • 从iOS8开始,接受的答案仍然按预期工作.你可能做错了什么.. (2认同)

Ja͢*_*͢ck 20

我稍微改进了Twan的答案,因为:

  1. 您的视图控制器可以设置为其他手势识别器的委托
  2. 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;
}
Run Code Online (Sandbox Code Playgroud)


rez*_*afi 10

请在root vc中设置:

-(void)viewDidAppear:(BOOL)animated{
    [super viewDidAppear:YES];
    self.navigationController.interactivePopGestureRecognizer.enabled = NO;

}

-(void)viewDidDisappear:(BOOL)animated{
    [super viewDidDisappear:YES];
    self.navigationController.interactivePopGestureRecognizer.enabled = YES;
}
Run Code Online (Sandbox Code Playgroud)


iPh*_*e 7 8

对于Swift:

navigationController!.interactivePopGestureRecognizer!.enabled = false
Run Code Online (Sandbox Code Playgroud)

  • 这有效,但我建议使用可选链接而不是强制解包.例如self.navigationController?.interactivePopGestureRecognizer?.isEnabled = false (11认同)

Zgp*_*ace 6

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

// disable
self.navigationController?.interactivePopGestureRecognizer?.isEnabled = false
// enable
self.navigationController?.interactivePopGestureRecognizer?.isEnabled = true
Run Code Online (Sandbox Code Playgroud)


dev*_*oul 5

编辑

如果要管理特定导航控制器的滑动功能,请考虑使用SwipeBack.

有了这个,你可以设置navigationController.swipeBackEnabled = NO.

例如:

#import <SwipeBack/SwipeBack.h>

- (void)viewWillAppear:(BOOL)animated
{
    navigationController.swipeBackEnabled = NO;
}
Run Code Online (Sandbox Code Playgroud)

它可以通过CocoaPods安装.

pod 'SwipeBack', '~> 1.0'
Run Code Online (Sandbox Code Playgroud)

我为缺乏解释而道歉.

  • 在宣传与您有关的项目时,您必须披露您与该项目的关系. (5认同)
  • 此外,您的项目的唯一目的是在默认系统不工作时手动启用滑动手势,而问题询问如何禁用该系统范围的手势,因此即使您设置了 `self.navigationController.swipeBackEnabled = NO` 我我很确定这只会禁用您图书馆的向后滑动手势,但系统的手势仍将启用。 (2认同)

Log*_*gic 5

它适用于ios 10及更高版本:

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

}
Run Code Online (Sandbox Code Playgroud)

它不适用于viewDidLoad()方法.