UINavigationBar是我们在开发过程中经常要用到的一个控件,下面我会为大家介绍一些常用的用法。
这个不多说,直接上代码self.navigationItem.title = @"UINavigationBar使用总结";
//通过barTintColor来设置背景色
self.navigationController.navigationBar.barTintColor = [UIColor redColor];
得到的效果如下:
barTintColor: 这个属性需要在iOS7以上才可以使用; 如果要支持iOS6以及以下的系统,可以参考这篇文章:UINavigationBar Background Color
除了通过设置背景颜色来改变导航栏的外观外,我们还可以通过背景图片来设置导航栏的外观。
[self.navigationController.navigationBar setBackgroundImage:[UIImage imageNamed:@"Background"]
forBarMetrics:UIBarMetricsDefault];
在这里得稍微说说UIBarMetrics这个枚举, 它主要是用来控制在不同状态下导航栏的显示。和UIButton的- (void)setBackgroundImage:(nullable UIImage *)image forState:(UIControlState)state
这个方法有点类似。
//表示横屏竖屏都显示
UIBarMetricsDefault,
//表示在只横屏下才显示,和UIBarMetricsLandscapePhone功效一样,不过iOS8已经弃用了
UIBarMetricsCompact,
UIBarMetricsDefaultPrompt和UIBarMetricsCompactPrompt这两个我还没搞清楚是什么意思,有知道的朋友不妨给我们来普及一下。。
从效果图可以看出,我们设置背景色或者背景图之后,状态栏依然还是默认的黑色,这样感觉不好看。好在,系统给我们提供了UIStatusBarStyleDefault和UIStatusBarStyleLightContent两种样式供我们选择。
下面来看看具体怎么实现,主流的实现方式是分两步:
-(UIStatusBarStyle)preferredStatusBarStyle{
return UIStatusBarStyleLightContent;
}
想知道更多地方式,可以参考这两个页面:How to change Status Bar text color in iOS 7 和 iOS7下Status Bar字体颜色修改
另外,特别需要注意的是,如果你的ViewController是通过navigationController push进来的,还需要加下面一句代码才能生效:
self.navigationController.navigationBar.barStyle = UIBarStyleBlack;
具体,可参考UIStatusBarStyle PreferredStatusBarStyle does not work on iOS 7
恩,我们来看看运行效果。
从上面的效果图中我们可以看到返回按钮还是默认的蓝色按钮,下面我将会大家来介绍返回按钮的个性化。
self.navigationController.navigationBar.tintColor = [UIColor whiteColor];
得到的效果图如下:- (void)goToBack {
[self.navigationController popViewControllerAnimated:YES];
}
- (void)setBackButtonWithImage {
UIImage *leftButtonIcon = [[UIImage imageNamed:@"LeftButton_back_Icon"]
imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
UIBarButtonItem *leftButton = [[UIBarButtonItem alloc] initWithImage:leftButtonIcon
style:UIBarButtonItemStyleBordered
target:self
action:@selector(goToBack)];
self.navigationItem.leftBarButtonItem = leftButton;
//修复navigationController侧滑关闭失效的问题
self.navigationController.interactivePopGestureRecognizer.delegate = (id)self;
}
得到的效果如下:
这里需要注意的地方有三点:
- 需要自己实现返回按钮的事件。
- 特别的解释下UIImage的imageWithRenderingMode:方法,参数UIImageRenderingModeAlwaysOriginal 表示总是用原图渲染,如果不这么设置,返回按钮将会显示tintColor的颜色(默认为蓝色)。UITabbarItem也存在同样地问题。
- 我们自己设置返回按钮,会导致系统的侧滑关闭效果失效。添加上面代码中最后一句代码即可修复。
- (void)setBackButtonTitle {
UIBarButtonItem *leftButton = [[UIBarButtonItem alloc] initWithTitle:NSLocalizedString(@"取消", nil)
style:UIBarButtonItemStylePlain
target:self action:@selector(goToBack)];
leftButton.tintColor = [UIColor whiteColor];
self.navigationItem.leftBarButtonItem = leftButton;
}
得到的效果如下:
- (void)setCustomLeftButton {
UIView* leftButtonView = [[UIView alloc]initWithFrame:CGRectMake(0, 0, 60, 40)];
UIButton* leftButton = [UIButton buttonWithType:UIButtonTypeSystem];
leftButton.backgroundColor = [UIColor clearColor];
leftButton.frame = leftButtonView.frame;
[leftButton setImage:[UIImage imageNamed:@"LeftButton_back_Icon"] forState:UIControlStateNormal];
[leftButton setTitle:@"返回" forState:UIControlStateNormal];
leftButton.tintColor = [UIColor redColor];
leftButton.autoresizesSubviews = YES;
leftButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeft;
leftButton.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleLeftMargin;
[leftButton addTarget:self action:@selector(goToBack) forControlEvents:UIControlEventTouchUpInside];
[leftButtonView addSubview:leftButton];
UIBarButtonItem* leftBarButton = [[UIBarButtonItem alloc] initWithCustomView:leftButtonView];
self.navigationItem.leftBarButtonItem = leftBarButton;
}
得到的效果图如下:
设置rightBarButtonItem基本上脱离不了上面的几种方式,大家可以参照上面返回按钮的设置方式。
有时候遇到一些特殊的要求,需要隐藏导航栏底部的线条。
两行代码就可以做到。
UINavigationBar *navigationBar = self.navigationController.navigationBar;
//设置透明的背景图,便于识别底部线条有没有被隐藏
[navigationBar setBackgroundImage:[[UIImage alloc] init]
forBarPosition:UIBarPositionAny
barMetrics:UIBarMetricsDefault];
//此处使底部线条失效
[navigationBar setShadowImage:[UIImage new]];
来看看效果图:
另外,还有一种做法,一行代码就可以达到效果,也真是够神奇的。。
//方法二:
self.navigationController.navigationBar.clipsToBounds = YES;
想要知道更详细的内容可以参考这个页面:How to hide iOS7 UINavigationBar 1px bottom line
有了上面的基础,设置导航栏线条的颜色就变得很简单了。
首先,我做了个UIImage的分类:通过颜色转成UIImage;
然后,用上面的方案来设置导航栏底部线条。
颜色转图片的代码:
@implementation UIImage (ColorImage)
+ (UIImage *)imageWithColor:(UIColor *)color
{
CGRect rect = CGRectMake(0.0f, 0.0f, 1.0f, 1.0f);
UIGraphicsBeginImageContext(rect.size);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetFillColorWithColor(context, [color CGColor]);
CGContextFillRect(context, rect);
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
}
@end
设置导航栏底部线条颜色的代码:
UINavigationBar *navigationBar = self.navigationController.navigationBar;
[navigationBar setBackgroundImage:[[UIImage alloc] init]
forBarPosition:UIBarPositionAny
barMetrics:UIBarMetricsDefault];
//此处使底部线条颜色为红色
[navigationBar setShadowImage:[UIImage imageWithColor:[UIColor redColor]]];
依照惯例,看下效果图:
当然还有其他的方式也可以做到,如addSubview, addSubLayer等。感兴趣的话可以参考下这个页面:iOS7 - Change UINavigationBar border color
最后,奉上Demo的地址:NavigationBarDemo