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

因为项目需求,需要解决两个功能点: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到指定控制器)