侧滑返回做法1:
前提条件:采用系统默认的返回按钮
弊端:必须从屏幕左侧的边缘滑动才会实现侧滑返回功能 [LS](https://pan.baidu.com/s/1skV1WOP 密码 zr7w)
- 代码:
// 直接调用系统的push方法,无需我们写pop时的代码
[self.navigationController pushViewController:vc1 animated:NO];
-
演示:
侧滑返回做法2:
前提条件:自定义导航栏返回按钮
弊端:必须从屏幕左侧的边缘滑动才会实现侧滑返回功能
- 代码:自定义导航栏返回按钮
#import "ZBNavController.h"
@interface ZBNavController ()<UINavigationControllerDelegate>
@property (nonatomic ,strong) id PopVCDelegate;
@end
@implementation ZBNavController
#warning 程序初始运行先执行pushViewController,方法执行完毕,才真真正正激情根控制器添加到屏幕上。然后加到屏幕时候,立刻调用navigationController,整个过程一气呵成.
- (void)viewDidLoad {
[super viewDidLoad];
// 导航控制器成为自己的代理。【必不可少,已验证】
// 既然任何类的对象都能成为导航控制器的代理,那么自己成为导航控制器的代理,有何不可呢?再者:成为代理,必须得遵守协议,设置代理对象是谁,实现代理方法,这三大核心步骤缺一不可。
self.delegate = self;
}
// 将要push到某个控制器的时候调用。参数viewController表示要push的控制器
- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated {
if (self.childViewControllers.count != 0) {
NSLog(@"非根控制器");
//加载图片
UIImage *image = [[UIImage imageNamed:@"NavBack"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
// 自定义导航栏的返回按钮
viewController.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithImage:image style:0 target:self action:@selector(back)];
}
//只要重写了pushViewController方法,里面一定要有这行代码,否则就不能实现控制器之间的跳转(入栈和出栈)
[super pushViewController:viewController animated:animated];
}
- (void)back {
// 返回上一级
[self popViewControllerAnimated:YES];
}
// 代理方法:导航控制器的View显示完毕时调用。 参数viewController要显示的控制器
-(void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated {
//判断当前显示的控制器是否为根控制器.
if(self.childViewControllers.count == 1) {
//是根控制器,设回手势代理。否则侧滑没反应,所以也就无法pop到上一级控制器。[已验证]
self.interactivePopGestureRecognizer.delegate = self.PopVCDelegate;
}
}
@end
全屏滑动返回
#import "ZBNavController.h"
@interface ZBNavController ()<UIGestureRecognizerDelegate>
@end
@implementation ZBNavController
- (void)viewDidLoad {
[super viewDidLoad];
// 滑动的手势
// 只要我们触发滑动的手势(滑动屏幕),系统就会调用self.interactivePopGestureRecognizer.delegate的handleNavigationTransition:方法,实现全屏返回功能。
// 系统底层帮我们实现了handleNavigationTransition:方法,我们只需要调用即可。
UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self.interactivePopGestureRecognizer.delegate action:@selector(handleNavigationTransition:)];
// 让当前控制器成为滑动手势的代理
pan.delegate = self;
[self.view addGestureRecognizer:pan];//给窗口的根控制器的view添加手势
}
//代理方法。判断是否开始响应手势,返回类型为BOOL.
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer {// C
//当前控制器是否为根控制器
if(self.childViewControllers.count == 1) {// 根控制器
return NO;// 拖动屏幕没有反应,即不会发生返回
}else {// 非根控制器
return YES;// 拖动屏幕有反应,即会发生返回
}
}
@end
拓展:自定义导航栏背景颜色,导航栏字体颜色,字体大小
- 代码:
#import "ZBNavController.h"
@interface ZBNavController ()
@end
@implementation ZBNavController
- (void)viewDidLoad {
[super viewDidLoad];
}
// 某个类或者子类重写了系统的initialize方法,只有在用这个类创建出对象的情况下,才会调用initialize方法,可能调用过多次
+ (void)initialize {
if (self == [ZBNavController class]) {
//获取整个应用程序下所有的导航条.
//UINavigationBar *bar = [UINavigationBar appearance];
//获取指定类下面的导航条
UINavigationBar *bar = [UINavigationBar appearanceWhenContainedInInstancesOfClasses:@[[ZBNavController class]]];
//导航条的背景图片
[bar setBackgroundImage:[UIImage imageNamed:@"NavBar64"] forBarMetrics:UIBarMetricsDefault];
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
// 导航栏的字体颜色
//根据可变字典中的key(即NSForegroundColorAttributeName),取出value,即使右边的[UIColor whiteColor]
dict[NSForegroundColorAttributeName] = [UIColor whiteColor];
// 导航栏的字体大小
dict[NSFontAttributeName] = [UIFont boldSystemFontOfSize:20];
[bar setTitleTextAttributes:dict];
}
}
@end
-
演示:
遇到的bug
- 出现的问题1:pop控制器的时候,有竖直的黑影
- 解决办法:给黑影所在的控制器设置背景颜色。
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor orangeColor];
}
参考部分链接
独立的导航控制器NavigationBar之间切换效果
实现的效果:pop时二级界面的导航栏不会消失隐藏.[LS](https://pan.baidu.com/s/1gfOBbUz 密码 8tma)
系统默认切换效果(共用一个导航条)
自定义切换效果(两个独立的导航条)
显示/隐藏navigationBar
- 在要push的控制器的viewWillAppear方法中设置navigationBar的隐藏或者显示
// 在viewWillAppear实现显示/隐藏navigationBar
-(void)viewWillAppear:(BOOL)animated{
self.navigationController.navigationBar.hidden = YES;
}