前言;本文篇幅不多,但是涉及到的内容却是开发中常用的。

涉及的内容:

  1、统一设置导航控制器子控制器的返回按钮。

  2、因为修改了系统的返回按钮,所以还需要设置手势事件。

  3、隐藏底部的工具条。

这里直接给出.m的实现文件,.h文件不需要,因为没有属性,没有自定义公开的方法。

 #import "YMNavigationController.h"

 @interface YMNavigationController () <UIGestureRecognizerDelegate>

 @end

 @implementation YMNavigationController
#pragma mark - 当前控制器的 生命周期方法
-(void)viewDidLoad{
// 设置屏幕手势事件监听的代理对象是self
self.interactivePopGestureRecognizer.delegate = self;
} #pragma mark - 重写父类的UINavigationController的方法
/**
* 重写push方法的目的:拦截所有push进来的子控制器
*
* @param viewController 刚刚push进来的子控制器
*
* 通过storyboard拖线push或者用纯代码push进来都会调用下面这个方法
*/
-(void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated{
// 如果viewController不是最早push进来的子控制器
// 这么去思考,返回按钮是属于上一个控制器的,点击返回按钮,回到上一个控制器嘛
// 返回按钮不是属于当前显示的控制器的
// 所以设置返回按钮的控制器就是从第1个子控制器开始的,也就是下面的>0的判断写法
if (self.childViewControllers.count > ) { // 处理左上角的返回按钮
UIButton* backButton = ({
UIButton* backButton = [UIButton buttonWithType:UIButtonTypeCustom];
//hy:这里需要设置按钮的image,根据需求不需要设置title
[backButton setImage:[UIImage imageNamed:@""] forState:UIControlStateNormal];
[backButton setImage:[UIImage imageNamed:@""] forState:UIControlStateHighlighted];
[backButton setTitle:@"返回" forState:UIControlStateNormal];
[backButton setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
[backButton setTitleColor:[UIColor redColor] forState:UIControlStateHighlighted];
[backButton sizeToFit];// 图片自动适应按钮大小
//hy:然后这里设置按钮的内边距的偏移量 (上,左,下,右) 需要按照需求去改改
backButton.contentEdgeInsets = UIEdgeInsetsMake(, -, , );
[backButton addTarget:self action:@selector(back) forControlEvents:UIControlEventTouchUpInside];
backButton;
}); // 将上面这个自定义的按钮设置到导航控制器的返回按钮上
viewController.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:backButton];
// 隐藏底部的工具条
viewController.hidesBottomBarWhenPushed = YES;
}
// 上面设置搞定后,再push控制器显示出来
[super pushViewController:viewController animated:YES];
} #pragma mark - <UIGestureRecognizerDelegate>
/**
* 手势识别对象会调用这个代理方法来决定手势是否有效
*
* @return YES : 手势有效, NO : 手势无效
*/
-(BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer{
// 当前,导航控制器的子控制器有2个以上的时候,手势有效。
return self.childViewControllers.count > ;
} #pragma mark - 按钮监听的方法
// 导航控制器返回按钮监听的方法
-(void)back{
[self popViewControllerAnimated:YES];
} @end

另外补充一个开发小细节,先看到上面的代码第47~48两行,也就是下面图中的第55~56行:

因为IOS开发是经常用懒加载的思想,所以在这个push方法被调用之前,如果使用了ViewController的view的属性或者和view相关的属性,就是调用ViewController的viewDidLoad方法。

也就是说,如果外部在push方法之前,就调用了ViewController的一些方法,比如setBackground,就会提前加载viewDidLoad以及里面的代码,然后调用push方法就会调用上面重写的UINavigationController的push方法,这样这重写push方法里面的设置会覆盖掉之前viewDidLoad里面的代码设置。

但是,如果把外部调用了ViewController的一些方法,比如setBackground,都放在viewDidLoad方法里面,就会出现,因为在调用push方法之前没有调用相关的view属性或者view方法,懒加载导致ViewController暂时没有调用viewDidLoad方法,所以就去执行上面重写的push方法,最后到了第56行(上面截图),将ViewController传递给pushViewController方法,底层显然会使得调用viewDidLoad方法,这时候viewDidLoad方法会被执行。

最新文章

  1. ThreadLocal对象使用过程中容易陷入的坑
  2. AnjularJS异步编程 Promise和$q
  3. Three.js学习(相机,场景,渲染,形状)
  4. SQL语句---nvl 用法
  5. java JVM垃圾回收机制
  6. jQuery选择器大全(48个代码片段+21幅图演示)
  7. DataTable 分页
  8. HTMLPARSER.NET 参考资料
  9. 锋利jQuery 学习整理之 第六章 jQuery 与Ajax 的应用
  10. Reward HDU
  11. php-mysql 问题笔记一——在命令行中可以执行的sql语句,无法从php页面页面执行!
  12. Custom Voice 操作步骤
  13. C++自学成长之路(第一篇)
  14. Sonar本地环境搭建
  15. python re 库的使用
  16. 应该掌握的JQuery的7个效果
  17. 【洛谷】3375 KMP字符串匹配
  18. 【BZOJ】4753: [Jsoi2016]最佳团体 01分数规划+树上背包
  19. [转](译)KVO的内部实现
  20. 截取Excel字符串的部分字符

热门文章

  1. 使用stdarg.h实现可变长度参数
  2. Android 学习笔记之网络通信基础+WebView....
  3. Hibernate中延迟加载和缓存
  4. [团队项目] Scrum 项目 3.0 SCRUM 流程的步骤2: Spring 计划
  5. C#使用基类的引用 and 虚方法和覆写方法
  6. Android --- 斗地主 [牌桌实现源码]
  7. sql 执行时间
  8. php中的字符串常用函数(三) str_replace() 子字符串替换
  9. Python可变参数
  10. SharpGL学习笔记(十八) 解析3ds模型并显示