UINavigationController的侧滑返回遇到的坑

来源:互联网 发布:淘宝5.9.5版本下载 编辑:程序博客网 时间:2024/06/05 04:26
    如果我们的控制器是由UINavigationController管理的话,我们就需要注意一下导航栏的侧滑返回.    一般来来说正常的页面布局不会出现侧滑返回的问题.首先,我先说明一下,实现这个需求有很多种方法.    就比如说上次在群里看到一个哥们不用push而是用的modal.然后自定义modal的转场动画.    然后侧滑返回用的是手势.还有禁止手势上下移动什么的.还需要开关手势等一大堆操作.业务逻辑十分的复杂

解决方式

    一般我们自定义UINavigation都是直接让子类继承与UINavigationController.    既然能够侧滑,肯定有相应的属性是来控制侧滑的.    通过查找UINavigationController的头文件,我发现了有这么一个属性,虽说没有注释.    <@property(nullable, nonatomic, readonly) UIGestureRecognizer *interactivePopGestureRecognizer>    Gesture是不是很熟悉.对,这是一个手势.关于UINavigationController的手势,我能想到的就是一个侧滑.    我们可以通过手势的    <@property(nonatomic, getter=isEnabled) BOOL enabled;      // default is YES. disabled gesture recognizers will not receive touches.     when changed to NO the gesture recognizer will be cancelled      if it's currently recognizing a gesture>    我们可以在第二个页面以<self.navigationController.interactivePopGestureRecognizer.enabled = NO;>    的方式来关闭来侧滑返回.同理可以设置为YES来开启侧滑返回.    对于上面的需求.我们可以通过scrollView的代理方法来解决.    首先.因为页面上有tableView(tableView继承与scrollView).    为了后期维护的方便,我们需要在scrollView的代理方法里面判断scrollView == scrollView.    然后通过判断scrollView的contentOffset的x属性来开关导航栏的侧滑手势的enabled属性.    这样就简单的解决了问题.    再也不用怕到第二个tableView在左边右滑直接dismiss到上一个控制器了

注意

问题1:

    因为我们设置了导航栏的手势的开关.因为导航栏的管理着这些push的页面.所以导航栏的生命周期比这些管理的页面长.    我们会发现.返回到上一页面的时候手势的使能是开着的.然后就会有很奇怪的效果.    我们可以在不需要使用侧滑的第一页的viewWillApper的方法里面把手势的使能设置为NO就行了.

问题2:

    类似于问题1.因为改动成no.如果在其他不需要设置使能的页面里面.侧滑手势就被禁用了.    我们是不是也能通过viewWillAppear来处理呢?    对于这个问题,第一.解决问题的方式有很多.这个做法是完全没有错误的.    但是,一个APP基本上不可能只有一两个页面.如果每个页面都需要设置一下使能.那代码的复杂度就起来了.    对于这个问题.我们能够想到.这些页面都是push出来的.push出来的,那么总要有一个方法来push吧.    通过查询UINavigationController的方法.有一个    <- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated>    我们可以在这个方法里面    - (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated {        if (self.viewControllers.count >= 1) {        NSLog(@"控制器:%@",viewController);        [super pushViewController:viewController animated:animated];        NSLog(@"控制器:%@",viewController);        }    }    我们可以发现第一个NSLog出来的是之前的push之前的控制器.第二个NSLog的是第二个控制器.    那么我们就可以在[super pushViewController:viewController animated:animated];这个方法来做开关了.     另.打个比方.如果我们以上来就是一个nav管理的viewController.一上来就会走    <- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated>    这个方法.但是dismiss到上一个控制器却不会走这个方法.所以我们需要在上来的时候设置一次NO.
阅读全文
0 0
原创粉丝点击