• IOS开发之功能模块--自定义导航控制器类常用自定义的代码


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

    涉及的内容:

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

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

      3、隐藏底部的工具条。

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

     1 #import "YMNavigationController.h"
     2 
     3 @interface YMNavigationController () <UIGestureRecognizerDelegate>
     4 
     5 @end
     6 
     7 @implementation YMNavigationController
     8 #pragma mark - 当前控制器的 生命周期方法
     9 -(void)viewDidLoad{
    10     // 设置屏幕手势事件监听的代理对象是self
    11     self.interactivePopGestureRecognizer.delegate = self;
    12 }
    13 
    14 #pragma mark - 重写父类的UINavigationController的方法
    15 /**
    16  *  重写push方法的目的:拦截所有push进来的子控制器
    17  *
    18  *  @param viewController 刚刚push进来的子控制器
    19  *
    20  *  通过storyboard拖线push或者用纯代码push进来都会调用下面这个方法
    21  */
    22 -(void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated{
    23     // 如果viewController不是最早push进来的子控制器
    24     // 这么去思考,返回按钮是属于上一个控制器的,点击返回按钮,回到上一个控制器嘛
    25     // 返回按钮不是属于当前显示的控制器的
    26     // 所以设置返回按钮的控制器就是从第1个子控制器开始的,也就是下面的>0的判断写法
    27     if (self.childViewControllers.count > 0) {
    28         
    29         // 处理左上角的返回按钮
    30         UIButton* backButton = ({
    31             UIButton* backButton = [UIButton buttonWithType:UIButtonTypeCustom];
    32             //hy:这里需要设置按钮的image,根据需求不需要设置title
    33             [backButton setImage:[UIImage imageNamed:@""] forState:UIControlStateNormal];
    34             [backButton setImage:[UIImage imageNamed:@""] forState:UIControlStateHighlighted];
    35             [backButton setTitle:@"返回" forState:UIControlStateNormal];
    36             [backButton setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
    37             [backButton setTitleColor:[UIColor redColor] forState:UIControlStateHighlighted];
    38             [backButton sizeToFit];// 图片自动适应按钮大小
    39             //hy:然后这里设置按钮的内边距的偏移量 (上,左,下,右) 需要按照需求去改改
    40             backButton.contentEdgeInsets = UIEdgeInsetsMake(0, -20, 0, 0);
    41             [backButton addTarget:self action:@selector(back) forControlEvents:UIControlEventTouchUpInside];
    42             backButton;
    43         });
    44         
    45         // 将上面这个自定义的按钮设置到导航控制器的返回按钮上
    46         viewController.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:backButton];
    47         // 隐藏底部的工具条
    48         viewController.hidesBottomBarWhenPushed = YES;
    49     }
    50     // 上面设置搞定后,再push控制器显示出来
    51     [super pushViewController:viewController animated:YES];
    52 }
    53 
    54 #pragma mark - <UIGestureRecognizerDelegate>
    55 /**
    56  *  手势识别对象会调用这个代理方法来决定手势是否有效
    57  *
    58  *  @return YES : 手势有效, NO : 手势无效
    59  */
    60 -(BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer{
    61     // 当前,导航控制器的子控制器有2个以上的时候,手势有效。
    62     return self.childViewControllers.count > 1;
    63 }
    64 
    65 #pragma mark - 按钮监听的方法
    66 // 导航控制器返回按钮监听的方法
    67 -(void)back{
    68     [self popViewControllerAnimated:YES];
    69 }
    70 
    71 @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方法会被执行。

  • 相关阅读:
    static的全部用法收集整理
    文思创新复试及一些自己的思考
    “一碗牛肉面”引发的管理难题
    信必优面试实录
    我做PM(项目经理)这段时间...
    什么是面向对象?
    沟通
    体会Bind和Eval的不同用法
    北京艾德思奇科技有限公司面试实录
    今天去sony公司面试实录
  • 原文地址:https://www.cnblogs.com/goodboy-heyang/p/4719931.html
Copyright © 2020-2023  润新知