因为项目需求,需要解决两个功能点: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
的代理UINavigationControllerDelegat
e,导入#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];
}
}
}