[iOS]自定义导航栏(RMNavigationBar)

GitHub:https://github.com/Gamin-fzym/GACustomNavDemo

系统的导航(UINavigationController)有时没法搞定需求,使用自定义的导航好处理些。
也不是什么复杂的内容,下面主要代码备个份。

RMNavigationBar 

#import <UIKit/UIKit.h>

@interface RMNavigationBar : UIView

///  标题Label,通过类方法传入title初始化, 只读
@property (nonatomic,   weak, readonly) UILabel * titleLabel;
///  自定义view,通过类方法初始化, 只读
@property (nonatomic,   weak, readonly) UIView * customView;
///  右侧按钮集合,通过类方传入rightItems法初始化,只读
@property (nonatomic,   copy, readonly) NSArray<UIButton *> *rightButtons;
///  右侧按钮
@property (nonatomic,   weak) UIButton * rightButton;
///  返回按钮
@property (nonatomic,   weak) UIButton * leftButton;
///  分隔线
@property (nonatomic,   weak) UIView * diveder;

@property (nonatomic,   copy) void (^rightBtnAction)(NSInteger index);

///  设置成白色主题
- (void)setupToWhiteTheme;

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

///  只有标题和返回键
///
///  @param title      标题
///  @param backAction 返回事件
///
///  @return 导航栏
+ (instancetype)navWithTitle:(NSString *)title
                  backAction:(void(^)(void))backAction;


/// 标题 + 右边item(图片或文字都行)(没有返回按钮)
/// @return 导航栏
+ (instancetype)navWithTitle:(NSString *)title
                   rightItem:(NSString *)rightItem
                 rightAction:(void(^)(void))action;


///  标题 + 右边item(图片或文字都行) + 返回按钮
///
///  @param title      标题
///  @param rightItem  右侧图片/文字
///  @param action     右侧点击事件
///  @param backAction 返回事件
///
///  @return 导航栏
+ (instancetype)navWithTitle:(NSString *)title
                   rightItem:(NSString *)rightItem
                 rightAction:(void(^)(void))action
                  backAction:(void(^)(void))backAction;

///  标题 + 右边item(图片或文字都行) + 返回按钮
///
///  @param customView 自定义view
///  @param rightItem  右侧图片/文字
///  @param action     右侧点击事件
///  @param backAction 返回事件
///
///  @return 导航栏
+ (instancetype)navWithCustomView:(UIView *)customView
                        rightItem:(NSString *)rightItem
                      rightAction:(void(^)(void))action
                       backAction:(void(^)(void))backAction;

///  标题 + 右边items(图片或文字都行) + 返回按钮
///
///  @param title      标题
///  @param rightItems 右侧图片/文字
///  @param action     右侧点击事件
///  @param backAction 返回事件
///
///  @return 导航栏
+ (instancetype)navWithTitle:(NSString *)title
                  rightItems:(NSArray<NSString *> *)rightItems
                 rightAction:(void(^)(NSInteger index))action
                  backAction:(void(^)(void))backAction;

/**
 自定义左右按钮
 */
+ (instancetype)navWithTitle:(NSString *)title
                     lefItem:(id)leftItem
                  leftAction:(void(^)(void))leftAction
                   rightItem:(NSString *)rightItem
                 rightAction:(void(^)(void))rightAction;

/**
自定义视图自定义尺寸
*/
+ (instancetype)navWithCustomView:(UIView *)customView
                            frame:(CGRect)frame
                       backAction:(void(^)(void))backAction;

/// 删除分隔线
- (void)removeDivider;

@end


@interface UIViewController (NavigatiionBar)

@property (nonatomic, strong) RMNavigationBar * rm_navgationBar;

@end
#import <objc/runtime.h>
#import "RMNavigationBar.h"
#import "CommonHeader.h"

/// 返回按钮图片
static NSString * BackButtonImageName = @"导航返回";
///  标题文字大小
static CGFloat    TitleFont           = 18;
///  按钮文字大小
static CGFloat    ButtonFont          = 15;
typedef void (^ButtonClick)(void);

@interface RMNavigationBar ()

@property (nonatomic,   copy) ButtonClick backBlock;
@property (nonatomic,   copy) ButtonClick actionBlock;
@end

@implementation RMNavigationBar

- (instancetype)initWithFrame:(CGRect)frame {
    
    if (self = [super initWithFrame:frame]) {
        
        UIInterfaceOrientation sataus=[UIApplication sharedApplication].statusBarOrientation;
        if (sataus == UIInterfaceOrientationLandscapeRight) {
            self.size = Size(SCREENWIDTH, NAVBARHEIGHT);
        }else{
            self.size = Size(SCREENHEIGHT, NAVBARHEIGHT);
        }
        [self addTransitionColor:HexColor(@"#2F4DA2") endColor:HexColor(@"#1E7FD7")];
        // 分隔线
        UIView * diveder = [UIView new];
        diveder.frame = Rect(0, NAVBARHEIGHT - 0.5, SCREENWIDTH, 0.5);
        diveder.backgroundColor = HexColorInt32_t(307859);
        [self addSubview:diveder];
        [self bringSubviewToFront:diveder];
        _diveder = diveder;
    }
    return self;
}

- (void)removeDivider {
    [_diveder removeFromSuperview];
}

- (instancetype)initWithObject:(id)obj rights:(NSArray *)rights rightAction:(void (^)(NSInteger))action backAction:(void (^)(void))backAction {
    
    if (self = [super init]) {
        CGFloat centerY = 20 + (NAVBARHEIGHT - 20) / 2;
        // 标题
        UIView * centerView = nil;
        if ([obj isKindOfClass:NSString.class]) {
            
            UILabel * label =  [UILabel labelWithText:obj font:TitleFont textColor:ThemeTitleColor frame:Rect(45, NAVBARHEIGHT - 44, SCREENWIDTH - 90, 42)];
            label.font = [UIFont boldSystemFontOfSize:TitleFont];
            [self addSubview:label];
            _titleLabel = (UILabel *)label;
            label.textAlignment = NSTextAlignmentCenter;
            label.lineBreakMode = NSLineBreakByTruncatingMiddle;
            centerView = label;
        } else if ([obj isKindOfClass:UIView.class]) {
            UIView * objView = obj;
            [self addSubview:objView];
            if (objView.height > 44) {
                objView.height = 44;
            }
            if (objView.width > SCREENWIDTH - 120) {
                objView.width = SCREENWIDTH - 120;
            }
            objView.center = Point(SCREENWIDTH/2.0f, centerY);
            centerView = objView;
            _customView = objView;
        }
        
        // 如果实现了右边的事件,会创建右边的按钮
        if (action) {
            CGFloat maxX = SCREENWIDTH - 7;
            NSMutableArray * btns = @[].mutableCopy;
            for (int i = 0; i < rights.count; i++) {
                NSString * right = rights[i];
                UIButton * rightBtn = nil;
                UIImage * image = [UIImage rm_imageNamed:right];
                if (image) {
                    if (i == 0) maxX -= 3;
                    rightBtn = [UIButton buttonWithTitle:nil titleColor:[UIColor whiteColor] backgroundColor:nil font:0 image:right frame:Rect(0, HeightStatusBar, 44, 44)];
                    [self addSubview:rightBtn];
                    rightBtn.maxX = maxX;
                    maxX = rightBtn.x;
                } else {
                    if (i == 0) maxX -= 8;
                    if ([right length]) {
                        CGSize size = [NSString getStringRect:right fontSize:ButtonFont width:300];
                        rightBtn = [UIButton buttonWithTitle:right titleColor:[UIColor whiteColor] backgroundColor:nil font:ButtonFont image:nil frame:Rect(0, HeightStatusBar, size.width, 44)];
                        [self addSubview:rightBtn];
                        rightBtn.maxX = maxX;
                        maxX = rightBtn.x - 7;
                    }
                }
                rightBtn.tag = i;
                [rightBtn addTarget:self action:@selector(rightBtnClick:)];
                self.rightBtnAction = action;
                if (rightBtn) [btns addObject:rightBtn];
            }
            if (btns.count == 1) {
                self.rightButton = [btns lastObject];
            } else {
                _rightButtons = [btns copy];
            }
        }
        
        // 如果实现了返回的事件,才创建返回按钮
        if (backAction) {
            UIButton * back = [UIButton buttonWithTitle:nil titleColor:nil backgroundColor:nil font:ButtonFont image:BackButtonImageName frame:Rect(0, HeightStatusBar, 44, 44)];
            [back addTarget:self action:@selector(backClick)];
     
            back.adjustsImageWhenHighlighted = NO;
            [self addSubview:back];
            self.backBlock = backAction;
            self.leftButton = back;
        }
        
    }
    return self;
}

#pragma mark - ButtonAction
- (void)btnClick {
    !self.actionBlock ? : self.actionBlock();
}

- (void)backClick {
    !self.backBlock ? : self.backBlock();
}

- (void)rightBtnClick:(UIButton *)btn {
    btn.selected = !btn.selected;
    BLOCK_SAFE_RUN(self.rightBtnAction, btn.selected);
}

- (void)setupToWhiteTheme {
    self.backgroundColor = [UIColor whiteColor];
    self.titleLabel.textColor = HexColorInt32_t(000000);
    self.rightButton.titleColor = HexColorInt32_t(333333);
    self.leftButton.image = [UIImage imageNamed:@"btn_back_gray"];
    [_diveder removeFromSuperview];
}

#pragma mark - 类方法
+ (instancetype)navWithTitle:(NSString *)title rightItem:(NSString *)rightItem rightAction:(void (^)(void))action {
    RMNavigationBar * nav = [[self alloc] initWithObject:title rights:rightItem.length ? @[rightItem] :nil rightAction:^(NSInteger index) {
        BLOCK_SAFE_RUN(action);
    } backAction:nil];
    return nav;
}

+ (instancetype)navWithTitle:(NSString *)title {
//    return [[self alloc] initWithObject:title right:nil rightAction:nil backAction:nil];
    RMNavigationBar * nav = [[self alloc] initWithObject:title rights:nil rightAction:nil backAction:nil];
    return nav;
}

+ (instancetype)navWithTitle:(NSString *)title backAction:(void (^)(void))backAction {
//    return [[self alloc] initWithObject:title right:nil rightAction:nil backAction:backAction];
    RMNavigationBar * nav = [[self alloc] initWithObject:title rights:nil rightAction:nil backAction:backAction];
    return nav;
}

+ (instancetype)navWithTitle:(NSString *)title rightItem:(NSString *)rightItem rightAction:(void (^)(void))action backAction:(void (^)(void))backAction {
//    return [[self alloc] initWithObject:title right:rightItem rightAction:action backAction:backAction];
    RMNavigationBar * nav = [[self alloc] initWithObject:title rights:rightItem.length ? @[rightItem] :nil rightAction:^(NSInteger index) {
        BLOCK_SAFE_RUN(action);
    } backAction:backAction];
    return nav;
}

+ (instancetype)navWithCustomView:(UIView *)costomView rightItem:(NSString *)rightItem rightAction:(void (^)(void))action backAction:(void (^)(void))backAction {
//    return [[self alloc] initWithObject:costomView right:rightItem rightAction:action backAction:backAction];
    
    RMNavigationBar * nav = [[self alloc] initWithObject:costomView rights:rightItem.length ? @[rightItem] :nil rightAction:^(NSInteger index) {
        BLOCK_SAFE_RUN(action);
    } backAction:backAction];
    return nav;
}

+ (instancetype)navWithTitle:(NSString *)title rightItems:(NSArray<NSString *> *)rightItems rightAction:(void(^)(NSInteger index))action backAction:(void(^)(void))backAction {
    return [[self alloc] initWithObject:title rights:rightItems rightAction:action backAction:backAction];
}

//自定义左右按钮
+ (instancetype)navWithTitle:(NSString *)title
                     lefItem:(id)leftItem
                  leftAction:(void(^)(void))leftAction rightItem:(NSString *)rightItem rightAction:(void(^)(void))rightAction
{
    
    RMNavigationBar * nav = [[self alloc] initWithObject:title rights:rightItem.length ? @[rightItem] : nil rightAction:^(NSInteger index) {
        BLOCK_SAFE_RUN(rightAction);
    } backAction:leftAction];
    UIImage *img = nil;
    if ([leftItem isKindOfClass:[NSString class]]) {
        img = ImageWithName(leftItem);
    }else{
        img = leftItem;
    }
    if (img) {
        [nav.leftButton setImage:img forState:UIControlStateNormal];
    } else if (!img && [leftItem isKindOfClass:NSString.class]) {
        [nav.leftButton setImage:nil forState:UIControlStateNormal];
        [nav.leftButton setTitle:leftItem forState:UIControlStateNormal];
        [nav.leftButton sizeToFit];
        nav.leftButton.centerY = nav.titleLabel.centerY;
    }
    return nav;
}

+ (instancetype)navWithCustomView:(UIView *)customView
                            frame:(CGRect)frame
                       backAction:(void(^)(void))backAction
{
    RMNavigationBar *nav = [[RMNavigationBar alloc] init];
    if (customView) {
        CGFloat x = backAction ? frame.origin.x + 44 : frame.origin.x;
        customView.frame = Rect(x, frame.origin.y, frame.size.width, frame.size.height);
        [nav addSubview:customView];
    }
    // 如果实现了返回的事件,才创建返回按钮
    if (backAction) {
        nav.backBlock = backAction;
        UIButton * back = [UIButton buttonWithTitle:nil titleColor:nil backgroundColor:nil font:ButtonFont image:BackButtonImageName frame:Rect(0, HeightStatusBar, 44, 44)];
        [back addTarget:nav action:@selector(backClick)];
        back.adjustsImageWhenHighlighted = NO;
        [nav addSubview:back];
    }
    return nav;
}
@end


static const char NavgationBarkey = '\0';
@implementation UIViewController (NavigatiionBar)

- (void)setRm_navgationBar:(RMNavigationBar *)rm_navgationBar {
    
    if (self.rm_navgationBar != rm_navgationBar) {
        [self.rm_navgationBar removeFromSuperview];
        [self.view addSubview:rm_navgationBar];
        objc_setAssociatedObject(self, &NavgationBarkey, rm_navgationBar, OBJC_ASSOCIATION_ASSIGN);
    }
}

- (RMNavigationBar *)rm_navgationBar {
    return objc_getAssociatedObject(self, &NavgationBarkey);
}

@end
#ifndef CommonHeader_h
#define CommonHeader_h

#import "UIView+TransitonColor.h"
#import "UIView+LYKit.h"
#import "UIColor+HexColor.h"
#import "UIView+YND.h"
#import "UIImage+Extension.h"
#import "UIButton+Extension.h"
#import "NSString+Category.h"

#define SCREENWIDTH [UIScreen mainScreen].bounds.size.width
#define SCREENHEIGHT [UIScreen mainScreen].bounds.size.height

#define IS_IPHONE_X (SCREENHEIGHT == 812.0f || SCREENHEIGHT == 896.0f) ? YES : NO
#define NAVBARHEIGHT  ((IS_IPHONE_X== YES)?88.0f: 64.0f)
#define HeightStatusBar ((IS_IPHONE_X == YES)?44.0f: 20.0f)

/// CGRect
#define Rect(x, y, w, h) CGRectMake((x), (y), (w), (h))
/// CGSize
#define Size(w, h) CGSizeMake((w), (h))
/// CGPoint
#define Point(x, y) CGPointMake((x), (y))

#define HexColor(hexString) [UIColor colorWithHexString:(hexString)]
#define HexColorInt32_t(rgbValue) \
[UIColor colorWithRed:((float)((0x##rgbValue & 0xFF0000) >> 16))/255.0 green:((float)((0x##rgbValue & 0x00FF00) >> 8))/255.0 blue:((float)(0x##rgbValue & 0x0000FF))/255.0  alpha:1]

//图片 URL
#define ImageWithName(nameString) [UIImage imageNamed:nameString]

///  主题色
#define ThemeTitleColor HexColorInt32_t(FFFFFF)

///  安全运行block
#define BLOCK_SAFE_RUN(block, ...) block ? block(__VA_ARGS__) : nil;


#endif /* CommonHeader_h */

示意图:







 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 适合毕业设计、课程设计作业。这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。 所有源码均经过严格测试,可以直接运行,可以放心下载使用。有任何使用问题欢迎随时与博主沟通,第一时间进行解答!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值