UINavigationContoller interactivePopGestureRecognizer 在导航栏隐藏时不活动

Posted

技术标签:

【中文标题】UINavigationContoller interactivePopGestureRecognizer 在导航栏隐藏时不活动【英文标题】:UINavigationContoller interactivePopGestureRecognizer inactive when navigation bar is hidden 【发布时间】:2013-11-07 10:48:08 【问题描述】:

我有一个嵌套在 UINavigationController 中的视图控制器。

我已经实现了 ios 7 interactivePopGestureRecognizer 以使用户能够通过手势将 VC 从堆栈中弹出。

在 VC 中,我有一个滚动视图,虽然用户不在滚动视图的顶部,但我隐藏了所有 chrome(导航栏和状态栏)以将焦点放在内容上。

但是在隐藏导航栏的情况下,interactivePopGestureRecognizer 无法正常工作。

我尝试在它消失并验证它不是 nil 后启用它,但它仍然不起作用。

我有什么遗漏吗?

【问题讨论】:

【参考方案1】:

将您的 UIViewController 子类设置为 gestureRecognizer 的委托:

self.navigationController.interactivePopGestureRecognizer.delegate = self;

就是这样!

【讨论】:

谢谢,实际上将它设置为 nil 也可以。我想知道这是否是一个错误? self.navigationController.interactivePopGestureRecognizer.delegate 设置为 self 或 nil 会有一个 bug:从屏幕边缘滑动,然后点击某物将视图控制器快速推入导航控制器,然后-- 1.当前视图控制器没有响应任何触摸事件; 2. 新的视图控制器不会显示; 3. 再次从屏幕边缘滑动,将显示新的视图控制器; 4.调用popViewControllerAnimated:动画参数设置为NO(点击自定义后退按钮),crash! 看起来只是设置委托是不够的,请参阅@iwill 的崩溃报告。我们发现的解决方法是存储原始委托,例如在viewDidLoad 中,将自己设置为viewDidAppear: 中的新人,然后再次将其重置为viewDidDisappear: 中的原始人。有点奇怪,但有效。 我不会推荐这个解决方案。它在展示/弹出视图控制器时导致了几个错误。 你应该在 viewDidAppear -(void)viewDidAppear:(BOOL)animated self.navigationController.interactivePopGestureRecognizer.delegate = self; 【参考方案2】:

简单的解决方案

不通过导航控制器设置导航栏的隐藏属性

就用这两行

self.navigationController.navigationBarHidden = NO;
self.navigationController.navigationBar.hidden = YES;

【讨论】:

【参考方案3】:

我用过这个。 self.navigationController.interactivePopGestureRecognizer.delegate = self;

在我的 UINavigationController 类中也可以在转换期间禁用 interactivePopGestureRecognizer。

- (void)pushViewController:(UIViewController *)viewController
              animated:(BOOL)animated

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


    [super pushViewController:viewController animated:animated];


- (void)navigationController:(UINavigationController *)navigationController
       didShowViewController:(UIViewController *)viewController
                    animated:(BOOL)animated

    if ([navigationController respondsToSelector:@selector(interactivePopGestureRecognizer)]) 
        // disable interactivePopGestureRecognizer in the rootViewController of navigationController
        if ([[navigationController.viewControllers firstObject] isEqual:viewController]) 
            navigationController.interactivePopGestureRecognizer.enabled = NO;
         else 
            // enable interactivePopGestureRecognizer
            navigationController.interactivePopGestureRecognizer.enabled = YES;
        
    

在rootViewController中禁用interactivePopGestureRecognizer的原因是:当从rootViewController的边缘滑动,然后点击一些东西推送到下一个viewController,UI现在不会接受任何触摸。按home键将应用程序置于后台,然后点击它进入前台...

【讨论】:

【参考方案4】:

这似乎对我不起作用。我关注了 Keithl 的博客文章。那也没有用。

我最终选择了UISwipeGestureRecognizer。它似乎按照它所说的去做。

UISwipeGestureRecognizer *gestureRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(backButtonPressed:)];
[gestureRecognizer setDirection:(UISwipeGestureRecognizerDirectionRight)];
[self.navigationController.view addGestureRecognizer:gestureRecognizer];

【讨论】:

您的意思是使用UIEdgePanGestureRecognizer 不是一个理想的解决方案,但它会在紧要关头完成。【参考方案5】:

将这两行添加到-(void)viewDidAppear:(BOOL)animated 对我有用。

self.navigationController.navigationBarHidden = NO;
self.navigationController.navigationBar.hidden = YES;

别忘了将<UIGestureRecognizerDelegate> 调用到.h 文件。

【讨论】:

以上是关于UINavigationContoller interactivePopGestureRecognizer 在导航栏隐藏时不活动的主要内容,如果未能解决你的问题,请参考以下文章

UINavigationController的使用介绍

为啥 Decimal.Divide(int, int) 有效,但 (int / int) 无效?

int32、int、int32_t、int8和int8_t的区别

int32,int,int32_t,int8和int8_t之间的区别

int *ptrl=(int*)(&a+1); int *ptr=(int*)((int)a+1);这两个定义有啥区别?

将 int(C::*)(int, char) 类型转换为 int(int, char) 类型