导航栏(Navigation Bar),顾名思义就是导航界面中的条状区域,一般在界面的顶部、底部、左侧或右侧位置,用来展示各种操作按钮和导航信息。很多移动应用程序都采用了导航栏来提高用户体验。而通过自定义导航栏样式,可以为应用程序增添更多的特色和玩味性。
概述导航栏
在iOS平台上,每个页面都有一个UINavigationBar(以下简称NavigationBar),我们可以通过修改NavigationBar的属性来实现一个不同寻常的效果。而对于Android来说,ActionBar就是扮演着导航栏的角色。因此,在本文中将以iOS为例来介绍如何快速、简单地定制NavigationBar的各个属性。
常见属性
NavigationBar的属性一般是在视图控制器类的viewDidLoad方法中进行的,下面介绍比较常见的属性。其中很多属性在iOS 13之前未被推荐使用,因此不建议使用。列出的大部分属性在iOS 13及以后的版本中已无效。
1. 标题
``` objective-c
self.navigationItem.title = @"标题文本";
```
2. 左按钮
```
self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"myImage"] style:UIBarButtonItemStylePlain target:self action:@selector(leftAction)];
```
3. 右按钮
```
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(rightAction)];
```
4. 标题颜色
```
[self.navigationController.navigationBar setTitleTextAttributes:@{NSForegroundColorAttributeName:[UIColor redColor]}];
```
5. 背景颜色
```
self.navigationController.navigationBar.barTintColor = [UIColor blueColor];
```
6. 背景图片
```
[self.navigationController.navigationBar setBackgroundImage:[UIImage imageNamed:@"myBgImage"] forBarMetrics:UIBarMetricsDefault];
```
7. 状态栏样式
```
-(UIStatusBarStyle)preferredStatusBarStyle{
return UIStatusBarStyleLightContent;
}
```
8. 透明度
```
self.navigationController.navigationBar.translucent = YES;
```
9. 隐藏NavigationBar
```
self.navigationController.navigationBarHidden = YES;
```
10. 模糊效果
```
if ([self.navigationController.navigationBar respondsToSelector:@selector(setBackgroundImage:forBarMetrics:)]) {
[self.navigationController.navigationBar setBackgroundImage:[UIImage new] forBarMetrics:UIBarMetricsDefault];
self.navigationController.navigationBar.shadowImage = [UIImage new];
self.navigationController.navigationBar.translucent = YES;
}
```
如何设计你自己的NavigationBar
下面开始介绍如何根据需要来设计NavigationBar
1. 设置NavigationBar的背景色和标题颜色
既然需要改变NavigationBar的样式,很自然想到是改变NavigationBar的颜色。需要注意的时,在iOS7之后,NavigationBar默认的translucent为YES。这意味着视图控制器的视图(原始区域)会考虑到NavigationBar的透明度而向上偏移约44px,而NavigationBar本身则会偏离原始区域顶部。
```
self.navigationController.navigationBar.translucent = NO; // 不透明
self.navigationController.navigationBar.barTintColor = [UIColor whiteColor];
self.navigationController.navigationBar.tintColor = [UIColor colorWithRed:106/255.0 green:106/255.0 blue:106/255.0 alpha:1.0]; // 按钮颜色
NSDictionary *attributes = @{
NSForegroundColorAttributeName : [UIColor colorWithRed:224/255.0 green:224/255.0 blue:224/255.0 alpha:1.0],
NSFontAttributeName : [UIFont systemFontOfSize:18.0 weight:UIFontWeightMedium]};
[self.navigationController.navigationBar setTitleTextAttributes:attributes];
```
2. 自定义左右按钮
头像图片和按钮左边的字符串用红色渐变来代替虚拟化的背景。这个NavigationBar将有大约43像素的内边距。
```
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
// 是否隐藏导航栏
[self.navigationController setNavigationBarHidden:NO animated:animated];
/* 自定义导航栏左右按钮 */
UIButton *leftButton = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 44, 44)];
[leftButton setImage:[UIImage imageNamed:@"myImage"] forState:UIControlStateNormal];
[leftButton addTarget:self action:@selector(leftAction:) forControlEvents:UIControlEventTouchUpInside];
self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:leftButton];
UIButton *rightButton = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 44, 44)];
[rightButton setTitle:@"分享" forState:UIControlStateNormal];
[rightButton setTitleColor:[UIColor colorWithRed:32/255.0 green:161/255.0 blue:255/255.0 alpha:1.0] forState:UIControlStateNormal];
[rightButton addTarget:self action:@selector(rightAction:) forControlEvents:UIControlEventTouchUpInside];
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:rightButton];
/* 自定义导航栏背景色 */
[self.navigationController.navigationBar setBackgroundImage:[self imageWithColor:[UIColor colorWithRed:253/255.0 green:97/255.0 blue:111/255.0 alpha:1]] forBarMetrics:UIBarMetricsDefault];
/* 自定义导航栏标题 */
self.navigationItem.title = @"自定义NavigationBar";
self.navigationController.navigationBar.titleTextAttributes = @{
NSForegroundColorAttributeName : [UIColor whiteColor],
NSFontAttributeName : [UIFont systemFontOfSize:18.0 weight:UIFontWeightMedium]};
}
- (void)leftAction:(id)sender {
NSLog(@"left button clicked");
}
- (void)rightAction:(id)sender {
NSLog(@"right button clicked");
}
- (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;
}
```
3. 自定义返回按钮
在设计NavigationBar的时候,返回按钮的样式也是需要考虑的。通过[self.navigationController.navigationBar backIndicatorImage]方法可以获取返回按钮的自定义图片,如果自定义图片不存在,则自动使用默认图片。需要注意的是,需要在上个VC中设置返回按钮以便在当前VC中正确显示。
```
/* 前一个VC。将返回按钮自定义为空格符 */
UIViewController *vc1 = [[UIViewController alloc] init];
vc1.navigationItem.backBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@" " style:UIBarButtonItemStylePlain target:nil action:nil];
[self.navigationController pushViewController:vc1 animated:YES];
/* 当前VC。将返回按钮自定义为图片 */
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
// 是否隐藏导航栏
[self.navigationController setNavigationBarHidden:NO animated:animated];
self.navigationItem.title = @"返回按钮自定义为图片";
[self.navigationController.navigationBar setBackgroundImage:[UIImage imageNamed:@"myBgImage"] forBarMetrics:UIBarMetricsDefault];
// set back button image
UIImage *backButtonImage = [[UIImage imageNamed:@"myBackButton"] resizableImageWithCapInsets:UIEdgeInsetsMake(0, 20, 0, 0)];
[[UIBarButtonItem appearance] setBackButtonBackgroundImage:backButtonImage forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
[[UIBarButtonItem appearance] setBackButtonTitlePositionAdjustment:UIOffsetMake(NSIntegerMin, NSIntegerMin) forBarMetrics:UIBarMetricsDefault];
self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithImage:[[UIImage imageNamed:@"myImage"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal] style:UIBarButtonItemStylePlain target:self action:@selector(leftAction)];
}
- (void)leftAction {
NSLog(@"left action clicked");
}
```
4. 控制高度
navigationBar的高度往往都是固定的,但是在某种极端情况下(例如需要某种定制的效果)需要进行修改。在默认情况下,navigationBar的高度为44像素。当navigationBar的高度被修改的时候,很多其他属性,如背景图,文字位置等等都需要进行修改。
```
/* 自定义NavigationBar高度 */
@implementation UINavigationBar (Height)
- (CGSize)sizeThatFits:(CGSize)size {
CGSize newSize = CGSizeMake(self.frame.size.width,70);
return newSize;
}
- (void)layoutSubviews {
[super layoutSubviews];
for (UIView *subview in self.subviews) {
if (subview.frame.size.height > 0.0f) {
CGRect frame = subview.frame;
if (frame.origin.y <= 0.0f) {
frame.origin.y = ([[UIApplication sharedApplication] statusBarFrame].size.height);
subview.frame = frame;
}
}
}
}
@end
```
结束语
本文介绍了一些常用的NavigationBar属性和如何自定义NavigationBar。在进行自定义时,请保持基于系统默认的基础上进行修改,不要脱离系统规范。NavigationBar的美观与否,往往会影响整个应用的品质。因此,在设计时要心思细腻,注重细节,力求让用户感到无微不至的真诚love.