• iOS:导航控制器侧滑出栈实现


    介绍:在iOS中,导航控制器UINavigationController是默认实现左侧边缘侧滑手势出栈的,但是如果当开发者对导航控制器子控制实现自定义leftBaButtonItem时,这个侧滑功能就会失去效果,此时就需要我们在自定义的NavigationController中手动代码去实现了。有的时候为了提高用户体验,会试着进行全屏的侧滑返回,现在这个技术已经普遍应用到app中。下面就来介绍边缘侧滑和全屏侧滑返回。。。。。

    第一种方式:实现左侧边缘侧滑返回(系统自带的边缘侧滑,安全可靠)

    //
    //  KJNavgationController.m
    //
    //  Created by mac on 16/2/22.
    //  Copyright © 2016年 mac. All rights reserved.
    //
    
    #import "KJNavgationController.h"
    
    @interface KJNavgationController ()<UIGestureRecognizerDelegate,UINavigationControllerDelegate>
    
    @end
    
    @implementation KJNavgationController
    -(void)viewDidLoad{ [super viewDidLoad]; __weak KJNavgationController *weakSelf = self; if ([self respondsToSelector:@selector(interactivePopGestureRecognizer)]) { self.interactivePopGestureRecognizer.delegate = weakSelf; self.delegate = weakSelf; } } - (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated { //控制器入栈过程中禁用手势识别 if ([self respondsToSelector:@selector(interactivePopGestureRecognizer)]) self.interactivePopGestureRecognizer.enabled = NO; [super pushViewController:viewController animated:animated]; } #pragma mark UINavigationControllerDelegate - (void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animate { //控制器入栈之后,启用手势识别 if ([self respondsToSelector:@selector(interactivePopGestureRecognizer)]) self.interactivePopGestureRecognizer.enabled = YES; } - (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer { if ([self.childViewControllers count] == 1) { return NO; } return YES; } - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer { return YES; } //运行试一试,发现了新问题,手指在滑动的时候,被 pop 的 ViewController 中的 UIScrollView 会跟着一起滚动,这个效果看起来就很怪(知乎日报现在就是这样的效果),而且也不是原始的滑动返回应有的效果,那么就让我们继续用代码来解决吧 - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldBeRequiredToFailByGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer { return [gestureRecognizer isKindOfClass:UIScreenEdgePanGestureRecognizer.class]; } @end

    优点:实现简单,导航控制器中对全体viewController的侧滑功能可控,系统API绝对安全可靠,无手势冲突

    缺点:侧滑范围局限于左侧

    适用需求:只需左侧小范围触发侧滑时的首选实现方案。

    第二种方式:实现全屏侧滑返回(并不完善的全屏侧滑)

    //
    //  KJNavgationController.m
    //
    //  Created by mac on 16/2/22.
    //  Copyright © 2016年 mac. All rights reserved.
    //
    
    #import "KJNavgationController.h"
    
    @interface KJNavgationController ()<UIGestureRecognizerDelegate>
    
    @end
    
    @implementation KJNavgationController
    
    -(void)viewDidLoad{
        [super viewDidLoad];
        
        // 获取系统自带滑动手势的target对象
        id target = self.interactivePopGestureRecognizer.delegate;
        
        // 创建全屏滑动手势,调用系统自带滑动手势的target的action方法
        UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:target action:@selector(handleNavigationTransition:)];
        
        // 设置手势代理,拦截手势触发
        pan.delegate = self;
        
        // 给导航控制器的view添加全屏滑动手势
        [self.view addGestureRecognizer:pan];
        
        // 禁止使用系统自带的滑动手势
        self.interactivePopGestureRecognizer.enabled = NO;
        
    }

    // 什么时候调用:每次触发手势之前都会询问下代理,是否触发。 // 作用:拦截手势触发 - (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer { // 注意:只有非根控制器才有滑动返回功能,根控制器没有。 // 判断导航控制器是否只有一个子控制器,如果只有一个子控制器,肯定是根控制器 if (self.childViewControllers.count == 1) { // 表示用户在根控制器界面,就不需要触发滑动手势, return NO; } return YES; } @end

    优点:最简洁的全屏侧滑实现,导航控制器中对全体viewController的侧滑功能可控

    缺点:从右边往左边划动也能触发侧滑操作,有手势冲突,并不完美。且调用官方私有API

    另外:正是缺点的所在,和Cell的侧滑删除手势也是有冲突的,也就是说,免不了需要解决手势的冲突。

    适用需求:最好不用,毕竟缺点明显。(不过这个实现思路,确实值得称赞!)

    第三种方式:(集成最简单、功能最全面):

    链接地址下载DEMO,具体详情见github:https://github.com/forkingdog/FDFullscreenPopGesture


    使用截图
        

    优点:最全面的全屏侧滑实现,集成超简单,全体viewController的侧滑功能可控,不过得在ViewController内部去控制,稍微麻烦一点;另外,百度知道团队在维护该DEMO,功能会越来越完善,花样更多。

    缺点:调用官方私有API(不过已有上线作品,不影响上线,缺点可以忽略!)

    适用需求:目前最好的全屏侧滑实现方案。

    第四种方式:创建swipe扫动手势,实现全屏侧滑返回

    - (void)viewDidLoad
    {
        [super viewDidLoad];
         
        // 添加右滑手势
        [self addSwipeRecognizer];
    }
     
    #pragma mark 添加右滑手势
    - (void)addSwipeRecognizer
    {
        // 初始化手势并添加执行方法
        UISwipeGestureRecognizer *swipeRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(return)];
         
        // 手势方向
        swipeRecognizer.direction = UISwipeGestureRecognizerDirectionRight;
         
        // 响应的手指数
        swipeRecognizer.numberOfTouchesRequired = 1;
         
        // 添加手势
        [[self view] addGestureRecognizer:swipeRecognizer];
    }
     
    #pragma mark 返回上一级
    - (void)return
    {
        // 最低控制器无需返回
        if (self.viewControllers.count <= 1) return;
         
        // pop返回上一级
        [self popToRootViewControllerAnimated:YES];
    }
    
    
    //若在控制器之间跳转时需要做一些事情,可在自定义的控制器里添加下面两个方法
    #pragma mark push方法
    - (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated
    {
        // do something you want
        ...
        [super pushViewController:viewController animated:animated];
    }
     
    #pragma mark pop方法
    - (UIViewController *)popViewControllerAnimated:(BOOL)animated
    {
        // 比如停止网络请求
        ...
         
        return [super popViewControllerAnimated:animated];
    }
            

    优点:用户可以自定义扫动侧滑,没有手势冲突,虽使用官方私有API,但是安全。

    缺点:侧滑速度太快,不好控制器,不能中途停止侧滑。

    适用需求:根据个人需要决定。

    参看链接:

    http://www.cocoachina.com/ios/20150811/12897.html

    http://www.jianshu.com/p/349636eb3fca

    http://www.jianshu.com/p/f83acf1d337b

    http://my.oschina.net/cobish/blog/225260

  • 相关阅读:
    CART算法(转)
    分类算法:决策树(C4.5)(转)
    决策树与迭代决策树(转)
    随机森林(Random Forest)详解(转)
    Bagging和Boosting 概念及区别(转)
    迭代器与生成器
    Python代码这样写更优雅(转)
    python进行EDA探索性数据分析
    标准化与归一化(转)
    最小树形图(poj3164)
  • 原文地址:https://www.cnblogs.com/XYQ-208910/p/5430068.html
Copyright © 2020-2023  润新知