在开发过程中,如果你用的是传统的样式顶部20px的statusbar加上下面44高度的navigationBar的话, 这样的产品经理真的是太好了,很简单,但是现在越来越多的人自定义导航栏,看起来就没有系统那么呆板,但是我就是不想自定义,我想自己更改系统导航栏的各种属性和frame。
首先,看看自己需要什么样子的
1.导航栏底部的1px像素我要去掉,需要一个纯净的
2.导航栏的高度我要更改为例如100
3.导航栏高度变化的时候,里面的leftBarItem和rightBarItem以及titleView也要跟着垂直居中
下面请看图
上面列出了三个需要解决的问题,咱们来一个个解决,我这里用了递归,还不错哦
第一个问题:导航栏底部1px是什么,怎么让他不显示
先来看一张图,他到底是什么东东,我用的是Reveal打开的,你也可以用Xcode自带的
打开如下,这是图形界面
以下是树形图,对应的那个控件UIImageView
没错,就是他,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;
}
是不是很干净了,OK,那么第一个问题解决了
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)];
搞定啦,同学
天真的我以为,第二个问题解决之后呢,你往上面放UIBarButtonItem和NavigationItem的title是默认垂直居中的
然而现实是残酷的,内部layoutSubviews根本不知道在干嘛,为嘛不居中嘞???
现在的思路大概是,要在重新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];
基本上介绍到这里就结束了,看到这里的人,真心感谢你们,我认真写,你们开心看,十分感谢
本次Demo传送门:点击传送门下载Demo