Runtime练手---自定义导航栏(适配iPhone X)

之前遇到了很多关于导航栏的问题, 一直想封装一下, 以后就一劳永逸了, 一直没时间, 最近做项目, 实在忍不了了, 就直接封装了方法, 全局调用. 原理很简单, 使用Runtime动态的向类中添加方法,全局调用, 直接上代码吧!
创建一个类, 继承自UIView:

typedef void(^ClickBlock)(void);

@interface HBK_NavigationBar : UIView

/* 
 标题
 */
@property (nonatomic, strong) UILabel *titleLabel;

/* 
 最左边按钮 
 */
@property (nonatomic, strong) UIButton *leftFirstBtn;

/* 
 左边第二个按钮 
 */
@property (nonatomic, strong) UIButton *leftSecondBtn;

/* 
 最右边item 
 */
@property (nonatomic, strong) UIButton *rightFirstBtn;

/* 
 右边第二个item 
 */
@property (nonatomic, strong) UIButton *rightSecondBtn;


/**
 右边第三个item
 */
@property (nonatomic, strong) UIButton *rightThirdBtn;


/* 
 背景图片 
 */
@property (nonatomic, strong) UIImage *backgroundImage;

/*
 背景颜色
 */
@property (nonatomic, strong) UIColor *bgColor;

/*
 标题
 */
@property (nonatomic, copy) NSString *title;
 
/*
 标题字体大小
 */
@property (nonatomic, strong) UIFont *font;

/*
 标题颜色
 */
@property (nonatomic, strong) UIColor *titleColor;

/*
 导航栏下面的线
 */
@property (nonatomic, strong) CALayer * deviderLayer;

以上主要定义了一些基本控件, title的展示, 以及左边和右边的item,包括导航栏属性的设置, 背景色, 背景图片等!
下面这些主要就是一些方法了, 下面列举了两个。

**
 只有标题的navigationBar
 @param title 标题
 @return 导航栏
 */
+ (instancetype)HBK_setupNavigationBarWithTitle:(NSString *)title;


/**
 标题  ---> 返回按钮
 @param title 标题
 @param back 返回按钮
 @return 导航栏
 */
+ (instancetype)HBK_setupNavigationBarWithTitle:(NSString *)title
                                     backAction:(ClickBlock)back;

下面是.m的实现方法, 也是列举了部分方法。

- (instancetype)initWithFrame:(CGRect)frame {
    if (self = [super initWithFrame:frame]) {
        self.size = CGSizeMake(kScreenWidth, kNavBarHeight);
        self.backgroundColor = HexColorInt32_t(F8F8F8);
        // 分隔线
        CALayer * layer = [CALayer layer];
        layer.frame = CGRectMake(0, kNavBarHeight-0.5, kScreenWidth, 0.5);
        layer.backgroundColor = HexColorInt32_t(DDDDDD).CGColor;
        [self.layer addSublayer:layer];
        _deviderLayer = layer;
    }
    return self;
}

- (instancetype)initWithTitle:(NSString *)title
                    leftFirst:(NSString *)leftFirst
           leftFirstBtnAction:(ClickBlock)leftFirstAction
                   leftSecond:(NSString *)leftSecond
          leftSecondBtnAction:(ClickBlock)leftSecondAction
                   rightFirst:(NSString *)rightFirst
          rightFirstBtnAction:(ClickBlock)rightFirstAction
                  rightSecond:(NSString *)rightSecond
         rightSecondBtnAction:(ClickBlock)rightSecondAction
                   rightThird:(NSString *)rightThird
          rightThirdBtnAction:(ClickBlock)rightThirdAction {
    if (self = [super init]) {
        self.bgImageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, kScreenWidth, kNavBarHeight-0.5)];
        [self addSubview:self.bgImageView];
        
        UIView *bottomView = [[UIView alloc] initWithFrame:CGRectMake(0, self.maxY-44, kScreenWidth, 44)];
        [self addSubview:bottomView];
        //如果标题存在, 创建label
        if (title) {
            self.titleLabel = [[UILabel alloc] initWithFrame:(CGRectMake(0, 0, kScreenWidth, 44))];
            self.titleLabel.textAlignment = NSTextAlignmentCenter;
            self.titleLabel.font = [UIFont systemFontOfSize:18];
            self.titleLabel.text = title;
            [bottomView addSubview:self.titleLabel];
        }
        
        //左边第一个按钮(最左边)
        if (leftFirst) {
            self.leftFirstBtn = [UIButton buttonWithType:(UIButtonTypeCustom)];
            self.leftFirstBtn.frame = CGRectMake(10, 7, 30, 30);
            UIImage *image = [UIImage imageNamed:leftFirst];
            if (image) {
                [self.leftFirstBtn setImage:[UIImage imageNamed:leftFirst] forState:(UIControlStateNormal)];
            } else {
                [self.leftFirstBtn setTitle:leftFirst forState:(UIControlStateNormal)];
                self.leftFirstBtn.titleLabel.font = [UIFont systemFontOfSize:15];
                [self.leftFirstBtn setTitleColor:[UIColor blackColor] forState:(UIControlStateNormal)];
            }
            [self.leftFirstBtn addTarget:self action:@selector(leftFirstBtnAction) forControlEvents:(UIControlEventTouchUpInside)];
            self.leftFirstBlock = leftFirstAction;
            [bottomView addSubview:self.leftFirstBtn];
        }
        
        //左边第二个按钮
        if (leftSecond) {
            self.leftSecondBtn = [UIButton buttonWithType:(UIButtonTypeCustom)];
            self.leftSecondBtn.frame = CGRectMake(40, 27, 30, 30);
            UIImage *image = [UIImage imageNamed:leftSecond];
            if (image) {
                [self.leftSecondBtn setImage:[UIImage imageNamed:leftSecond] forState:(UIControlStateNormal)];
            } else {
                [self.leftSecondBtn setTitle:leftSecond forState:(UIControlStateNormal)];
                self.leftSecondBtn.titleLabel.font = [UIFont systemFontOfSize:15];
                [self.leftSecondBtn setTitleColor:[UIColor blackColor] forState:(UIControlStateNormal)];
            }
            [self.leftSecondBtn addTarget:self action:@selector(leftSecondBtnAction) forControlEvents:(UIControlEventTouchUpInside)];
            self.leftSecondBlock = leftSecondAction;
            [bottomView addSubview:self.leftSecondBtn];
        }
        
        //右边第一个按钮(最右边)
        if (rightFirst) {
            self.rightFirstBtn = [UIButton buttonWithType:(UIButtonTypeCustom)];
            self.rightFirstBtn.frame = CGRectMake(kScreenWidth-35, 7, 30, 30);
            UIImage *image = [UIImage imageNamed:rightFirst];
            if (image) {
                [self.rightFirstBtn setImage:[UIImage imageNamed:rightFirst] forState:(UIControlStateNormal)];
            } else {
                [self.rightFirstBtn setTitle:rightFirst forState:(UIControlStateNormal)];
                self.rightFirstBtn.titleLabel.font = [UIFont systemFontOfSize:15];
                [self.rightFirstBtn setTitleColor:[UIColor blackColor] forState:(UIControlStateNormal)];
            }
            [self.rightFirstBtn addTarget:self action:@selector(rightFirstBtnAction) forControlEvents:(UIControlEventTouchUpInside)];
            self.rightFirstBlock = rightFirstAction;
            [bottomView addSubview:self.rightFirstBtn];
        }
        
        //右边第二个按钮
        if (rightSecond) {
            self.rightSecondBtn = [UIButton buttonWithType:(UIButtonTypeCustom)];
            UIImage *image = [UIImage imageNamed:rightSecond];
            self.rightSecondBtn.frame = CGRectMake(kScreenWidth-70, 7, 30, 30);
            if (image) {
                [self.rightSecondBtn setImage:[UIImage imageNamed:rightSecond] forState:(UIControlStateNormal)];
            } else {
                [self.rightSecondBtn setTitle:rightSecond forState:(UIControlStateNormal)];
                self.rightSecondBtn.titleLabel.font = [UIFont systemFontOfSize:15];
                [self.rightSecondBtn setTitleColor:[UIColor blackColor] forState:(UIControlStateNormal)];

            }
            [self.rightSecondBtn addTarget:self action:@selector(rightSecondBtnAction) forControlEvents:(UIControlEventTouchUpInside)];
            self.rightSecondBlock = rightSecondAction;
            [bottomView addSubview:self.rightSecondBtn];
        }
        
        if (rightThird) {
            self.rightThirdBtn = [UIButton buttonWithType:(UIButtonTypeCustom)];
            self.rightThirdBtn.frame = CGRectMake(kScreenWidth-105, 7, 30, 30);
            UIImage *image = [UIImage imageNamed:rightThird];
            if (image) {
                [self.rightThirdBtn setImage:[UIImage imageNamed:rightThird] forState:(UIControlStateNormal)];
            } else {
                [self.rightThirdBtn setTitle:rightSecond forState:(UIControlStateNormal)];
                self.rightThirdBtn.titleLabel.font = [UIFont systemFontOfSize:15];
                [self.rightThirdBtn setTitleColor:[UIColor blackColor] forState:(UIControlStateNormal)];
            }
            [self.rightThirdBtn addTarget:self action:@selector(rightThirdBtnAction) forControlEvents:(UIControlEventTouchUpInside)];
            self.rightThirdBlock = rightThirdAction;
            [bottomView addSubview:self.rightThirdBtn];
        }
        
        
        
        
    }
    return self;
}



+ (instancetype)HBK_setupNavigationBarWithTitle:(NSString *)title {
    return [[self alloc] initWithTitle:title
                             leftFirst:nil
                    leftFirstBtnAction:nil
                            leftSecond:nil
                   leftSecondBtnAction:nil
                            rightFirst:nil
                   rightFirstBtnAction:nil
                           rightSecond:nil
                  rightSecondBtnAction:nil
                            rightThird:nil
                   rightThirdBtnAction:nil];
}



+ (instancetype)HBK_setupNavigationBarWithTitle:(NSString *)title
                                     backAction:(ClickBlock)back {
    return [[self alloc] initWithTitle:title
                             leftFirst:BackButtonImageName
                    leftFirstBtnAction:back
                            leftSecond:nil
                   leftSecondBtnAction:nil
                            rightFirst:nil
                   rightFirstBtnAction:nil
                           rightSecond:nil
                  rightSecondBtnAction:nil
                            rightThird:nil
                   rightThirdBtnAction:nil];
}


+ (instancetype)HBK_setupNavigationBarWithTitle:(NSString *)title
                                      leftFirst:(NSString *)leftFirst
                                leftFirstAction:(ClickBlock)leftFirstAction {
    return [[self alloc] initWithTitle:title
                             leftFirst:leftFirst
                    leftFirstBtnAction:leftFirstAction
                            leftSecond:nil
                   leftSecondBtnAction:nil
                            rightFirst:nil
                   rightFirstBtnAction:nil
                           rightSecond:nil
                  rightSecondBtnAction:nil
                            rightThird:nil
                   rightThirdBtnAction:nil];
}


+ (instancetype)HBK_setupNavigationBarWithTitle:(NSString *)title
                                      leftFirst:(NSString *)leftFirst
                                leftFirstAction:(ClickBlock)leftFirstAction
                                     leftSecond:(NSString *)leftSecond
                            leftSecondBtnAction:(ClickBlock)leftSecondAction {
    return [[self alloc] initWithTitle:title
                             leftFirst:leftFirst
                    leftFirstBtnAction:leftFirstAction
                            leftSecond:leftSecond
                   leftSecondBtnAction:leftSecondAction
                            rightFirst:nil
                   rightFirstBtnAction:nil
                           rightSecond:nil
                  rightSecondBtnAction:nil
                            rightThird:nil
                   rightThirdBtnAction:nil];
}

+ (instancetype)HBK_setupNavigationBarWithTitle:(NSString *)title
                                     rightFirst:(NSString *)rightFirst
                            rightFirstBtnAction:(ClickBlock)rightFirstAction {
    return [[self alloc] initWithTitle:title
                             leftFirst:nil
                    leftFirstBtnAction:nil
                            leftSecond:nil
                   leftSecondBtnAction:nil
                            rightFirst:rightFirst
                   rightFirstBtnAction:rightFirstAction
                           rightSecond:nil
                  rightSecondBtnAction:nil
                            rightThird:nil
                   rightThirdBtnAction:nil];
}

下面这些是重中之重,写完之后就全局调用了。

@class HBK_NavigationBar;

@interface UIViewController (NavigatiionBar)

@property (nonatomic, strong) HBK_NavigationBar * hbk_navgationBar;

@end

实现部分

//-------------------------------- 动态向类中添加方法 -----------------------------
#import "HBK_NavigationBar.h"
static const char NavgationBarkey = '\0';
@implementation UIViewController (NavigatiionBar)

- (void)setHbk_navgationBar:(HBK_NavigationBar *)hbk_navgationBar {
    if (self.hbk_navgationBar != hbk_navgationBar) {
        [self.hbk_navgationBar removeFromSuperview];
        [self.view addSubview:hbk_navgationBar];
        /**
         @param object#> 表示关联者,是一个对象,变量名理所当然也是object description#>
         @param key#> 获取被关联者的索引key description#>
         @param value#> 被关联者 description#>
         @param policy#> 关联时采用的协议,有assign,retain,copy等协议 description#>
         
         关键策略是一个枚举值。
         OBJC_ASSOCIATION_ASSIGN = 0,      <指定一个弱引用关联的对象>
         OBJC_ASSOCIATION_RETAIN_NONATOMIC = 1,<指定一个强引用关联的对象>
         OBJC_ASSOCIATION_COPY_NONATOMIC = 3,  <指定相关的对象复制>
         OBJC_ASSOCIATION_RETAIN = 01401,      <指定强参考>
         OBJC_ASSOCIATION_COPY = 01403    <指定相关的对象复制>
         */
        objc_setAssociatedObject(self, &NavgationBarkey, hbk_navgationBar, OBJC_ASSOCIATION_ASSIGN);
    }
}

- (HBK_NavigationBar *)hbk_navgationBar {
    return objc_getAssociatedObject(self, &NavgationBarkey);
}

重要的代码都贴上去了, 主要是Runtime的运用。
github地址查看完整demo。
https://huangbingke@github.com/huangbingke/HBKNavigationBar.git
欢迎提供宝贵意见!
码字不易,求打赏!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,383评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,522评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,852评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,621评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,741评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,929评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,076评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,803评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,265评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,582评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,716评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,395评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,039评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,798评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,027评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,488评论 2 361
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,612评论 2 350

推荐阅读更多精彩内容