iOS花式更改系统自带UINavigationBar导航栏样式,让你拥有更纯净,更强自定义的导航栏!!!It's amazing

在开发过程中,如果你用的是传统的样式顶部20px的statusbar加上下面44高度的navigationBar的话, 这样的产品经理真的是太好了,很简单,但是现在越来越多的人自定义导航栏,看起来就没有系统那么呆板,但是我就是不想自定义,我想自己更改系统导航栏的各种属性和frame。

首先,看看自己需要什么样子的

1.导航栏底部的1px像素我要去掉,需要一个纯净的

2.导航栏的高度我要更改为例如100

3.导航栏高度变化的时候,里面的leftBarItem和rightBarItem以及titleView也要跟着垂直居中

下面请看图

有瑕疵啊有瑕疵,底部的1px还在iOS花式更改系统自带UINavigationBar导航栏样式,让你拥有更纯净,更强自定义的导航栏!!!It's amazing_第1张图片

iOS花式更改系统自带UINavigationBar导航栏样式,让你拥有更纯净,更强自定义的导航栏!!!It's amazing_第2张图片


再来一张 这个就没有瑕疵了iOS花式更改系统自带UINavigationBar导航栏样式,让你拥有更纯净,更强自定义的导航栏!!!It's amazing_第3张图片

iOS花式更改系统自带UINavigationBar导航栏样式,让你拥有更纯净,更强自定义的导航栏!!!It's amazing_第4张图片


非常完美干净,有洁癖的看起来真的很舒服好么!!!iOS花式更改系统自带UINavigationBar导航栏样式,让你拥有更纯净,更强自定义的导航栏!!!It's amazing_第5张图片

上面列出了三个需要解决的问题,咱们来一个个解决,我这里用了递归,还不错哦

第一个问题:导航栏底部1px是什么,怎么让他不显示

先来看一张图,他到底是什么东东,我用的是Reveal打开的,你也可以用Xcode自带的

iOS花式更改系统自带UINavigationBar导航栏样式,让你拥有更纯净,更强自定义的导航栏!!!It's amazing_第6张图片


打开如下,这是图形界面

iOS花式更改系统自带UINavigationBar导航栏样式,让你拥有更纯净,更强自定义的导航栏!!!It's amazing_第7张图片

以下是树形图,对应的那个控件UIImageView

iOS花式更改系统自带UINavigationBar导航栏样式,让你拥有更纯净,更强自定义的导航栏!!!It's amazing_第8张图片


没错,就是他,UIImageView,Frame为0.5的那个,直接撸代码递归它

UIImageView *cancelImageView = [self searchNavigationBarUnderLine:self.navigationController.navigationBar];
    cancelImageView.hidden = YES;
- (UIImageView *)searchNavigationBarUnderLine:(UIView *)view
{
    // 查找是否属于UIImageView以及Frame是否小于1.0
    if ([view isKindOfClass:[UIImageView class]] && view.bounds.size.height < 1.0f)
    {
        return (UIImageView *)view;
    }
    // 循环第二层查找
    for (UIView *subView in view.subviews)
    {
        // 递归查找
        UIImageView *imageView = [self searchNavigationBarUnderLine:subView];
        if (imageView) {
            return imageView;
        }
    }
    return nil;
}

这行代码递归查找出是否有个控件UIImageView而且他的frame的高度是小于1.0的,这样就能把多余的1pxHidden了

iOS花式更改系统自带UINavigationBar导航栏样式,让你拥有更纯净,更强自定义的导航栏!!!It's amazing_第9张图片


是不是很干净了,OK,那么第一个问题解决了


第二个问题:如何更改导航栏的高度(这个东西有点棘手,去github找找资源)

JZNavigationExtension,就是他,帮你们找到现成的了,他能更改导航栏很多属性,咱们先用一个更改frame

传送门:点击打开链接


platform:ios,'7.0'

target '递归的方法取消1px'do

pod 'JZNavigationExtension'

end

之后你只要包括他的头文件

#import"JZNavigationExtension.h"

[self.navigationController setJz_navigationBarSize:CGSizeMake([UIScreen mainScreen].bounds.size.width, 100)];

搞定啦,同学

iOS花式更改系统自带UINavigationBar导航栏样式,让你拥有更纯净,更强自定义的导航栏!!!It's amazing_第10张图片


             


第三个问题:如何让导航栏上的控件垂直居中

天真的我以为,第二个问题解决之后呢,你往上面放UIBarButtonItem和NavigationItem的title是默认垂直居中的

      

然而现实是残酷的,内部layoutSubviews根本不知道在干嘛,为嘛不居中嘞???

iOS花式更改系统自带UINavigationBar导航栏样式,让你拥有更纯净,更强自定义的导航栏!!!It's amazing_第11张图片

现在的思路大概是,要在重新LayoutSubviews的时候重新进行居中,系统不居中,咱们自己写一个Category,调用父

类的同时子类重新布局,从而达到所有控件居中的效果

#import "UINavigationBar+CustomHeight.h"

@implementation UINavigationBar (CustomHeight)

- (CGSize)sizeThatFits:(CGSize)size {
    // Change navigation bar height. The height must be even, otherwise there will be a white line above the navigation bar.
    CGSize newSize = CGSizeMake(self.frame.size.width, 100);
    return newSize;
}

-(void)layoutSubviews {
    [super layoutSubviews];
    
    // Make items on navigation bar vertically centered.
    int i = 0;
        for (UIView *view in self.subviews) {
//            NSLog(@"<%i>. %@", i, [view description]);
            i++;
            // 这里的1是背景imageView,不需要进行配置
            if (i == 1)
                continue;
            // 这里的3就是titleView,不设置就会有bug,title不会跟着居中,需要手动调节他子视图Label的frame,这是个坑,一定要注意这样写
            if (i == 3)
            {
                for (UILabel *label in view.subviews) {
                    float y = (view.bounds.size.height - label.bounds.size.height) / 2;
                    CGRect rec = label.frame;
                    rec.origin.y = y;
                    label.frame = rec;
                }
            }
            [self alignVerticalCenter:view];
        }
    
}
- (void)alignVerticalCenter:(UIView *)view
{
    // 居中
    float centerY = self.bounds.size.height / 2.0f;
    CGPoint center = view.center;
    center.y = centerY;
    view.center = center;
}
这里写了一个方法自己查看UINavigationBar的所有视图的递归,大家可以跟着查看打印日志,这样对内部的控件布局 会更有理解
   [self logView:self.navigationController.navigationBar];
    
}


- (void)logView:(UIView *)view
{
    NSLog(@",%@",view.description);
    for (UIView *subView in view.subviews)
    {
        [self logView:subView];
    }
}

三个问题解决完了,这样你就能让你的导航栏随心所欲的变化了,去掉了底部1px,而且高度也能随时变化,内部控件

也都居中了,反正我的问题解决了,各位有什么新发现可以分享下


注:这里分享个UIBarButtonItem的间距和偏移问题

// 这个UIBarButtonSystemItemFixedSpace属性没有任何样式,是专门给item之间加间隙的 正数间距越大,负数就越小
    UIBarButtonItem *spaceItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace target:nil action:nil];
    spaceItem.width = 50;
    UIBarButtonItem *rightBarButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemPlay target:self action:@selector(clickRight)];
    self.navigationItem.rightBarButtonItems = @[spaceItem,rightBarButton];

效果就是这样的

iOS花式更改系统自带UINavigationBar导航栏样式,让你拥有更纯净,更强自定义的导航栏!!!It's amazing_第12张图片


基本上介绍到这里就结束了,看到这里的人,真心感谢你们,我认真写,你们开心看,十分感谢



本次Demo传送门:点击传送门下载Demo


你可能感兴趣的:(超实用Demo)