自定义NavigationBar

作者: 今晚月色 | 来源:发表于2018-07-15 13:59 被阅读516次
    b288ea7b0000a8cd1aae564cbfb20569.jpg

    本人小白,写的不是很好,希望大家见谅~~~
    自定义NavigationBar方法有很多种,今天介绍的这个适合初学者时候用。
    一、创建一个视图基础于UIView,并在视图中创建常用的按钮和标题, 里面视图的布局都是通过Masonry自动布局的,所以还是要导入Masonry。
    1、.h文件中声明按钮、按钮的点击事件和底部线条

    #import <UIKit/UIKit.h>
    #import <Masonry.h>
    
    #define IS_iPhoneX ([UIScreen mainScreen].bounds.size.width == 375 && [UIScreen mainScreen].bounds.size.height == 812)
    #define KStatusBarHeight (IS_iPhoneX ? 24.f:0.f)
    #define KStatusBarMargin (IS_iPhoneX ? 22.f:0.f)
    #define Screen_Height      [[UIScreen mainScreen] bounds].size.height
    #define Screen_Width       [[UIScreen mainScreen] bounds].size.width
    
    @interface WDNavBar : UIView
    // 主视图
    @property (nonatomic, strong) UIView    *mainView;
    // 左边第一个按钮
    @property (nonatomic, strong) UIButton  *leftButton;
    // 左边第二个按钮
    @property (nonatomic, strong) UIButton  *leftTwoButton;
    // 右边第一个按钮
    @property (nonatomic, strong) UIButton  *rightButton;
    // 右边第二个按钮
    @property (nonatomic, strong) UIButton  *rightTwoButton;
    // 标题按钮
    @property (nonatomic, strong) UIButton  *centerButton;
    // 是否显示底部线
    @property (nonatomic, assign) BOOL      showBottomLabel;
    
    @property (nonatomic, copy) void (^ leftButtonBlock)(void);
    @property (nonatomic, copy) void (^ leftTwoButtonBlock)(void);
    @property (nonatomic, copy) void (^ cenTerButtonBlock)(void);
    @property (nonatomic, copy) void (^ rightButtonBlock)(void);
    @property (nonatomic, copy) void (^ rightTwoButtonBlock)(void);
    
    @end  
    

    2、.m中懒加载视图控件

    #import "WDNavBar.h"
    
    @interface WDNavBar ()
    
    @property (nonatomic, strong) UILabel *lineLabel;
    @property (nullable, nonatomic, readonly) UIViewController *viewController;
    
    @end
    
    
    @implementation WDNavBar
    
    - (UIView *)mainView{
        if (!_mainView) {
            _mainView = [UIView new];
            _mainView.backgroundColor = [UIColor clearColor];
            [self addSubview:_mainView];
            [_mainView mas_makeConstraints:^(MASConstraintMaker *make) {
                make.left.right.top.bottom.mas_equalTo(0);
            }];
            [_mainView.superview layoutIfNeeded];
        }
        return _mainView;
    }
    
    - (UIButton *)leftButton{
        if (!_leftButton) {
            // 左边按钮
            _leftButton = [UIButton buttonWithType:UIButtonTypeCustom];
            _leftButton.titleLabel.font = [UIFont systemFontOfSize:15];
            _leftButton.adjustsImageWhenHighlighted = NO;
            _leftButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentCenter;
            [_leftButton setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
            [self.mainView addSubview:_leftButton];
            [_leftButton addTarget:self action:@selector(clickLeftButton) forControlEvents:UIControlEventTouchUpInside];
            [_leftButton mas_makeConstraints:^(MASConstraintMaker *make) {
                make.left.mas_equalTo(0);
                make.width.mas_equalTo(50);
                make.height.mas_equalTo(40);
                make.centerY.mas_equalTo(self.mainView.mas_centerY).with.offset((KStatusBarMargin+20)/2);
            }];
        }
        return _leftButton;
    }
    
    - (UIButton *)leftTwoButton{
        if (!_leftTwoButton) {
            // 左边第二个按钮
            _leftTwoButton = [UIButton buttonWithType:UIButtonTypeCustom];
            _leftTwoButton.titleLabel.font = [UIFont systemFontOfSize:15];
            _leftTwoButton.adjustsImageWhenHighlighted = NO;
            _leftTwoButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentCenter;
            [_leftTwoButton setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
            [self.mainView addSubview:_leftTwoButton];
            [_leftTwoButton addTarget:self action:@selector(clickLeftTwoButton) forControlEvents:UIControlEventTouchUpInside];
            [_leftTwoButton mas_makeConstraints:^(MASConstraintMaker *make) {
                make.left.mas_equalTo(self.leftButton.mas_right).mas_offset(10);
                make.width.mas_equalTo(50);
                make.height.mas_equalTo(40);
                make.centerY.mas_equalTo(self.mainView.mas_centerY).with.offset((KStatusBarMargin+20)/2);
            }];
        }
        return _leftTwoButton;
    }
    
    -(UIButton *)rightButton{
        if (!_rightButton) {
            //右边按钮
            UIButton *rightButton = [UIButton buttonWithType:UIButtonTypeCustom];
            rightButton.titleLabel.font = [UIFont systemFontOfSize:15];
            rightButton.adjustsImageWhenHighlighted = NO;
            [rightButton setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
            [self.mainView addSubview:rightButton];
            self.rightButton = rightButton;
            [_rightButton addTarget:self action:@selector(clickRightButton) forControlEvents:UIControlEventTouchUpInside];
            [self.rightButton mas_makeConstraints:^(MASConstraintMaker *make) {
                make.right.mas_equalTo(-5);
                make.width.mas_equalTo(50);
                make.height.mas_equalTo(40);
                make.centerY.mas_equalTo(self.leftButton);
            }];
            [self.rightButton.superview layoutIfNeeded];
        }
        return _rightButton;
    }
    
    -(UIButton *)rightTwoButton{
        if (!_rightTwoButton) {
            //右边第二个按钮
            UIButton *rightButton = [UIButton buttonWithType:UIButtonTypeCustom];
            rightButton.titleLabel.font = [UIFont systemFontOfSize:15];
            rightButton.adjustsImageWhenHighlighted = NO;
            [rightButton setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
            [self.mainView addSubview:rightButton];
            self.rightTwoButton = rightButton;
            [_rightTwoButton addTarget:self action:@selector(clickRightTwoButton) forControlEvents:UIControlEventTouchUpInside];
            [self.rightTwoButton mas_makeConstraints:^(MASConstraintMaker *make) {
                make.right.mas_equalTo(self.rightButton.mas_left).mas_offset(-10);
                make.width.mas_equalTo(50);
                make.height.mas_equalTo(40);
                make.centerY.mas_equalTo(self.leftButton);
            }];
            [self.rightTwoButton.superview layoutIfNeeded];
        }
        return _rightTwoButton;
    }
    
    -(UIButton *)centerButton{
        if (!_centerButton) {
            //中间按钮
            UIButton *centerButton = [UIButton buttonWithType:UIButtonTypeCustom];
            centerButton.titleLabel.font = [UIFont boldSystemFontOfSize:16];
            [centerButton setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
            centerButton.adjustsImageWhenHighlighted = NO;
            [self.mainView addSubview:centerButton];
            self.centerButton = centerButton;
            [_centerButton addTarget:self action:@selector(clickCenterButton) forControlEvents:UIControlEventTouchUpInside];
            [self.centerButton mas_makeConstraints:^(MASConstraintMaker *make) {
                make.centerX.mas_equalTo(self.mas_centerX);
                make.height.mas_equalTo(self.leftButton.mas_height);
                make.width.mas_equalTo(Screen_Width - (self.rightButton.width + 38) * 2);
                make.centerY.mas_equalTo(self.leftButton);
            }];
            [self.centerButton.superview layoutIfNeeded];
        }
        return _centerButton;
    }
    
    -(UILabel *)lineLabel{
        if (!_lineLabel) {
            //底部分割线
            UILabel *lineLabel = [[UILabel alloc] init];
            lineLabel.backgroundColor = UIColor.lightGrayColor;
            self.lineLabel = lineLabel;
            [self.mainView addSubview:lineLabel];
            [self.lineLabel mas_makeConstraints:^(MASConstraintMaker *make) {
                make.left.right.bottom.mas_equalTo(0);
                make.height.mas_equalTo(0.5);
            }];
            [self.mainView bringSubviewToFront:lineLabel];
        }
        return _lineLabel;
    }
    
    - (instancetype)initWithFrame:(CGRect)frame{
        if (self = [super initWithFrame:frame]) {
            self.backgroundColor = [UIColor whiteColor];
            [self setupUI];
        }
        return self;
    }
    
    /**
     *  UI 界面
     */
    - (void)setupUI{
        [self lineLabel];
    }
    
    - (void)setShowBottomLabel:(BOOL)showBottomLabel{
        self.lineLabel.hidden = !showBottomLabel;
    }
    - (UIViewController *)viewController {
        for (UIView *view = self; view; view = view.superview) {
            UIResponder *nextResponder = [view nextResponder];
            if ([nextResponder isKindOfClass:[UIViewController class]]) {
                return (UIViewController *)nextResponder;
            }
        }
        return nil;
    }
    
    #pragma mark - private
    - (void)clickLeftButton{
        //  获取返回视图的视图控制器
        [self.viewController.navigationController popViewControllerAnimated:YES];
        if (self.leftButtonBlock) {
            self.leftButtonBlock();
        }
    }
    
    - (void)clickLeftTwoButton{
        if (self.leftTwoButtonBlock) {
            self.leftTwoButtonBlock();
        }
    }
    
    
    - (void)clickCenterButton{
        if (self.cenTerButtonBlock) {
            self.cenTerButtonBlock();
        }
    }
    
    - (void)clickRightButton{
        if (self.rightButtonBlock) {
            self.rightButtonBlock();
        }
    }
    
    - (void)clickRightTwoButton{
        if (self.rightTwoButtonBlock) {
            self.rightTwoButtonBlock();
        }
    }
    
    @end
    

    二、使用方法
    1、因为需要兼容iPhone X,所以需要使用一下几个宏定义 如果有请直接替换就行)

    #define IS_iPhoneX ([UIScreen mainScreen].bounds.size.width == 375 && [UIScreen mainScreen].bounds.size.height == 812)
    #define KStatusBarHeight (IS_iPhoneX ? 24.f:0.f)
    #define KStatusBarMargin (IS_iPhoneX ? 22.f:0.f)
    #define Screen_Height      [[UIScreen mainScreen] bounds].size.height
    #define Screen_Width       [[UIScreen mainScreen] bounds].size.width
    

    2、在基类ViewController中隐藏系统导航栏

    self.navigationController.navigationBar.hidden = true;
    

    3、在基类的ViewController头文件里面声明属性 WDNavBar *navView,用于在任意继承于基类ViewController的控制器对导航栏进行进一步自定义

    @property (nonatomic, strong) WDNavBar *navView;
    

    4、加载视图,设置默认的属性

    -(WDNavBar *)navView{
             if (!_navView) {
                 WDNavBar *navView = [[WDNavBar alloc] init];
                 [self.view addSubview:navView];
                 // 设置导航栏背景颜色
                 navView.backgroundColor = [UIColor whiteColor];
                 self.navView = navView;
                 // 设置默认返回按钮图片
                 [self.navView.leftButton setImage:[UIImage  imageNamed:@"icon_back"]
                                          forState:UIControlStateNormal];
                 [self.navView mas_makeConstraints:^(MASConstraintMaker *make) {
                     make.left.right.top.mas_equalTo(0);
                     make.height.mas_equalTo(64 + KStatusBarHeight);
                 }];
                 [self.navView.superview layoutIfNeeded];
             }
            return _navView;
         }
    

    5、在需要的时候调用一下 其他页面的控件 如果使用自动布局 设置为self.navView.mas_bottom
    三、效果图


    自定义导航栏.gif

    四、补充Swift版本
    1、不废话直接上代码

    import UIKit
    import SnapKit
    
    class WDNavigationBar: UIView {
        
        private let kStatusBarheight = UIApplication.shared.statusBarFrame.size.height
        
        private var _showBottomLabel:Bool = true
        
        public var showBottomLabel:Bool {
            get{
                return _showBottomLabel
            }
            set{
                _showBottomLabel = showBottomLabel
                lineView.isHidden = !showBottomLabel
            }
        }
        
        var buttonClickBlock:((_ name:String) ->Void)?
        
        private func firstViewController() -> UIViewController? {
            for view in sequence(first: self.superview, next: { $0?.superview }) {
                if let responder = view?.next {
                    if responder.isKind(of: UIViewController.self){
                        return responder as? UIViewController
                    }
                }
            }
            return nil
        }
        
        private lazy var lineView:UIView = {
            let view = UIView.init()
            view.backgroundColor = UIColor.lightGray
            mainView.addSubview(view)
            view.snp.makeConstraints({ (make) in
                make.left.right.bottom.equalTo(0);
                make.height.equalTo(0.5);
            })
            mainView.bringSubview(toFront: view)
            return view
        }()
        
        lazy var mainView:UIView = {
            let view = UIView.init()
            view.backgroundColor = UIColor.clear
            self.addSubview(view)
            view.snp.makeConstraints({ (make) in
                make.left.right.top.bottom.equalTo(0);
            })
            view.superview?.layoutIfNeeded()
            return view
        }()
        
        lazy var leftButton:UIButton = {
            let button = setupButton(buttonTag: 10, fontSize: 16)
            button.snp.makeConstraints({ (make) in
                make.left.equalTo(0);
                make.width.equalTo(50);
                make.height.equalTo(40);
                make.centerY.equalTo(mainView.snp.centerY).offset((kStatusBarheight)/2);
            })
            button.superview?.layoutIfNeeded()
            return button
        }()
        
        lazy var leftSecondButton:UIButton = {
            let button = setupButton(buttonTag: 11, fontSize: 16)
            button.snp.makeConstraints({ (make) in
                make.left.equalTo(leftButton.snp.right).offset(10)
                make.width.equalTo(50)
                make.height.equalTo(40)
                make.centerY.equalTo(leftButton);
            })
            button.superview?.layoutIfNeeded()
            return button
        }()
        
        lazy var rightButton:UIButton = {
            let button = setupButton(buttonTag: 12, fontSize: 16)
            button.snp.makeConstraints({ (make) in
                make.right.equalTo(-5);
                make.width.equalTo(50);
                make.height.equalTo(40);
                make.centerY.equalTo(leftButton);
            })
            button.superview?.layoutIfNeeded()
            return button
        }()
        
        lazy var righSecondButton:UIButton = {
            let button = setupButton(buttonTag: 13, fontSize: 16)
            button.snp.makeConstraints({ (make) in
                make.right.equalTo(rightButton.snp.left).offset(-10);
                make.width.equalTo(50);
                make.height.equalTo(40);
                make.centerY.equalTo(leftButton);
            })
            button.superview?.layoutIfNeeded()
            return button
        }()
    
        lazy var centerButton:UIButton = {
            let button = setupButton(buttonTag: 14, fontSize: 18)
            button.snp.makeConstraints({ (make) in
                make.centerX.equalTo(self.snp.centerX);
                make.height.equalTo(leftButton.snp.height);
                make.width.equalTo(kScreenWidth - (rightButton.frame.size.width + 38) * 2);
                make.centerY.equalTo(leftButton);
            })
            button.superview?.layoutIfNeeded()
            return button
        }()
        
    
        override init(frame: CGRect) {
            super .init(frame: frame);
        }
        
        required init?(coder aDecoder: NSCoder) {
            fatalError("init(coder:) has not been implemented")
        }
        
        @objc private func buttonAction (sender:UIButton) {
         
            if sender.tag == 10 {
                firstViewController()?.navigationController?.popViewController(animated: true)
            }
            /// 这个地方有很多做法
            if (buttonClickBlock != nil) {
                buttonClickBlock!((sender.titleLabel?.text)!)
            }
        }
        
        /// 初始化按钮
        ///
        /// - Parameters:
        ///   - buttonTag: tag
        ///   - fontSize: 字体大小
        /// - Returns: button
        private func setupButton(buttonTag:Int,fontSize:CGFloat) -> UIButton {
            let button = UIButton.init()
            button.titleLabel?.font = UIFont.systemFont(ofSize: fontSize)
            button.adjustsImageWhenHighlighted = false
            button.setTitleColor(UIColor.black, for: .normal)
            button.tag = buttonTag
            button .addTarget(self, action: #selector(buttonAction(sender:)), for: .touchUpInside)
            mainView.addSubview(button)
            return button
        }
    }
    

    2、使用方法

       /// 自定义导航栏
       public lazy var wdNavgationBar:WDNavigationBar = {
            let wdNav = WDNavigationBar.init()
            view.addSubview(wdNav)
            wdNav.backgroundColor = UIColor.white
            wdNav.showBottomLabel = true
            wdNav.centerButton.setTitleColor(UIColor.white, for: .normal)
            wdNav.snp.makeConstraints { (make) in
                make.left.right.top.equalTo(0)
                make.height.equalTo(44 + UIApplication.shared.statusBarFrame.size.height)
            }
            return wdNav
        }()
        
        private var in_mainTitle:String?
        
        public var mainTitle:String {
            get{
                return in_mainTitle!
            }
            set {
                in_mainTitle = newValue
                // 直接设置中间按钮
                wdNavgationBar.centerButton.setTitle(mainTitle, for: .normal)
            }
        }
    

    五、如果有问题希望大家指正~~~

    相关文章

      网友评论

      • 写_Bug_小能手:为什么不用数组添加按钮呢,然后添加限制,最多添加几个
        今晚月色:@一场烟火_换你一世迷离 这个有待改进 谢谢提出的问题!

      本文标题:自定义NavigationBar

      本文链接:https://www.haomeiwen.com/subject/ucdppftx.html