美文网首页
iOS 点击左上角返回按钮Pop到指定控制器

iOS 点击左上角返回按钮Pop到指定控制器

作者: 硅谷干货 | 来源:发表于2017-10-20 11:29 被阅读29次

    因为项目需求,需要解决两个功能点:1.击每个页面的左上角的返回按钮,除了返回上一级页面之外,还需要Pop到根控制器,甚至是指定控制器(因为默认是返回上一级,所以在这里只列举其他两种情况!)。2.关闭系统默认屏边滑动返回功能

    1. 自定义QDNavigationController类

    因为我自定义了继承自UINavigationController 的类QDNavigationController,并且重写了系统UINavigationController的代理UINavigationControllerDelegate的方法:- (void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated以控制每个页面的的屏边手势滑动返回功能,在我自定义的QDNavigationController.h类头文件中添加了代码如下:

    1.1 QDNavigationController.h

    typedef NS_OPTIONS(NSInteger, QDVCType){
        QDVCTypePreVC,
        QDVCTypeRootVC,
        QDVCTypeTargetVC,
    };
    
    @interface QDNavigationController : UINavigationController
    
    @property (nonatomic, strong) id popDelegate;
    
    @property (nonatomic, assign) QDVCType type;
    
    @property (nonatomic, strong) UIViewController *targetVC;
    
    @end
    

    1.2 QDNavigationController.m

    QDNavigationController.m实现文件如下:

    //导航控制器跳转完成时候的调用
    - (void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated{
        if (viewController == self.viewControllers[0]) {//显示根控制器
            self.interactivePopGestureRecognizer.delegate = _popDelegate;
            
        }else{//不是显示根控制器
            self.interactivePopGestureRecognizer.delegate = nil;//清空滑动返回手势的代理,就能实现滑动功能
            
        }
    }
    
    - (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated{
        
        if (self.childViewControllers.count) { //不是根控制器
            
            viewController.hidesBottomBarWhenPushed = YES;
            
            UIBarButtonItem *left = [UIBarButtonItem barButtonItemWithImage:[UIImage imageNamed:@"icon_back_topbar"] highImage:[UIImage imageNamed:@"icon_back_topbar"] title:nil target:self action:@selector(popToPre) forControlEvents:UIControlEventTouchUpInside];
            // 设置导航条的按钮
            viewController.navigationItem.leftBarButtonItem = left;
        }
        return [super pushViewController:viewController animated:animated];
    }
    
    - (void)popToPre{
        
        switch (self.type) {
            case QDVCTypePreVC:
                [self popViewControllerAnimated:YES];
                break;
            case QDVCTypeRootVC:
                [self popToRootViewControllerAnimated:YES];
                break;
            case QDVCTypeTargetVC:
                [self popToAppointVC:self.targetVC];
                break;
            default:
                break;
        }
    }
    

    2. 返回到根控制

    现在在实现自定义Pop并且禁掉手势的页面导入#import "QDNavigationController.h" 头文件,接着代码实现如下:

    - (void)viewDidLoad {
        [super viewDidLoad];
        
        self.navigationController.delegate = self;//让当前控制器成为导航的代码
    }
    
    - (void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated{
        
        QDNavigationController *naviVC = (QDNavigationController *)navigationController;
        if (viewController == navigationController.viewControllers[0]) {
            //1.显示根控制器,不能滑动
            naviVC.interactivePopGestureRecognizer.delegate = naviVC.popDelegate;//1.1.禁掉手机屏边收拾返回滑动功能
            naviVC.type = QDVCTypePreVC;//1.2.恢复返回的类型
        }else{
            //2.不是显示根控制器,清空滑动返回手势的代理,就能实现滑动功能
            if ([viewController isKindOfClass:[QDForgetController class]]) {
                naviVC.interactivePopGestureRecognizer.delegate = naviVC.popDelegate;//2.1.禁掉手机屏边收拾返回滑动功能
                naviVC.type = QDVCTypeRootVC;//2.2.指定返回的类型
            }else{
                naviVC.interactivePopGestureRecognizer.delegate = nil;//2.4.恢复手机屏边收拾返回滑动功能
                naviVC.type = QDVCTypePreVC;//2.5.恢复返回的类型
            }
        }
    
    //3.解决与父视图重叠问题
        //3.1.获取主主窗口
        UIWindow *keyWindow = [UIApplication sharedApplication].keyWindow;
        UITabBarController *tabBarVC = (UITabBarController *) keyWindow.rootViewController;
        //3.2.移除系统tabBarButton
        for (UIView *tabBarButton in tabBarVC.tabBar.subviews) {
            if ([tabBarButton isKindOfClass:NSClassFromString(@"UITabBarButton")]) {
                [tabBarButton removeFromSuperview];
            }
        }
    }
    

    3. 返回到根指定控制器

    同样需要遵守系统UINavigationController的代理UINavigationControllerDelegate,导入#import "QDNavigationController.h"头文件,和返回根控制器不同的是需要指定一个控制器对象,接着直接代码实现如下:

    - (void)viewDidLoad {
        [super viewDidLoad];
        
        self.navigationController.delegate = self;//让当前控制器成为导航的代码
    }
    - (void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated{
        
        QDNavigationController *naviVC = (QDNavigationController *)navigationController;
        if (viewController == navigationController.viewControllers[0]) {
            //1.显示根控制器,不能滑动
            naviVC.interactivePopGestureRecognizer.delegate = naviVC.popDelegate;//1.1.禁掉手机屏边收拾返回滑动功能
            naviVC.type = QDVCTypePreVC;//1.2.恢复返回的类型
            naviVC.targetVC = nil;//1.3.清空跳转指定控制器
        }else{
            //2.不是显示根控制器,清空滑动返回手势的代理,就能实现滑动功能
            if ([viewController isKindOfClass:[QDForgetController class]]) {
                naviVC.interactivePopGestureRecognizer.delegate = naviVC.popDelegate;//2.1.禁掉手机屏边收拾返回滑动功能
                naviVC.type = QDVCTypeTargetVC;//2.2.指定返回的类型
                naviVC.targetVC = [[QDLoginController alloc] init];//2.3.设置要跳转的指定控制器
            }else{
                naviVC.interactivePopGestureRecognizer.delegate = nil;//2.4.恢复手机屏边收拾返回滑动功能
                naviVC.type = QDVCTypePreVC;//2.5.恢复返回的类型
                naviVC.targetVC = nil;//2.6.清空跳转指定控制器
            }
        }
    //解决跳转问题
        QDNavigationController *naviVC = (QDNavigationController *)navigationController;
        if (viewController == navigationController.viewControllers[0]) {
            //1.显示根控制器,不能滑动
            //1.1.禁掉手机屏边收拾返回滑动功能
            naviVC.interactivePopGestureRecognizer.delegate = naviVC.popDelegate;
            //1.2.恢复返回的类型
            naviVC.type = QDVCTypePreVC;
        }else{
            //2.不是显示根控制器,清空滑动返回手势的代理,就能实现滑动功能
            if ([viewController isKindOfClass:[self class]]) {
                naviVC.interactivePopGestureRecognizer.delegate = naviVC.popDelegate;//2.1.禁掉手机屏边收拾返回滑动功能
                naviVC.type = QDVCTypeRootVC;//2.2.指定返回的类型
            }else{
                naviVC.interactivePopGestureRecognizer.delegate = nil;//2.4.恢复手机屏边收拾返回滑动功能
                naviVC.type = QDVCTypePreVC;//2.5.恢复返回的类型
            }
        }
        
        //3.解决与父视图重叠问题
        //3.1.获取主主窗口
        UIWindow *keyWindow = [UIApplication sharedApplication].keyWindow;
        UITabBarController *tabBarVC = (UITabBarController *) keyWindow.rootViewController;
        //3.2.移除系统tabBarButton
        for (UIView *tabBarButton in tabBarVC.tabBar.subviews) {
            if ([tabBarButton isKindOfClass:NSClassFromString(@"UITabBarButton")]) {
                [tabBarButton removeFromSuperview];
            }
        }
    }
    

    相关文章

      网友评论

          本文标题:iOS 点击左上角返回按钮Pop到指定控制器

          本文链接:https://www.haomeiwen.com/subject/udnmuxtx.html