UINavigationBar 使用总结

UINavigationBar是我们在开发过程中经常要用到的一个控件,下面是UINavigationBar一些常用的用法,部分代码我使用了OC和Swift书写

1. 设置导航栏的标题
self.navigationItem.title = @"UINavigationBar使用总结";

注意:修改导航栏的字体大小和颜色

self.navigationController?.navigationBar.titleTextAttributes = [NSForegroundColorAttributeName: UIColor.whiteColor(), NSFontAttributeName: UIFont.systemFontOfSize(24)]

得到的效果如下:

Paste_Image.png
2. 设置导航栏的背景颜色-barTintColor
 self.navigationController.navigationBar.barTintColor = [UIColor redColor];

得到的效果如下:

barTintColor: 这个属性需要在iOS7以上才可以使用; 如果要支持iOS6以及以下的系统,可以参考这篇文章:UINavigationBar Background Color

3. 设置导航栏的背景图片

除了通过设置背景颜色来改变导航栏的外观外,我们还可以通过背景图片来设置导航栏的外观。

[self.navigationController.navigationBar setBackgroundImage:[UIImage imageNamed:@"Background"] forBarMetrics:UIBarMetricsDefault];

在这里得稍微说说UIBarMetrics这个枚举, 它主要是用来控制在不同状态下导航栏的显示。
和UIButton的- (void)setBackgroundImage:(nullable UIImage *)image forState:(UIControlState)state这个方法有点类似。

4. 更改顶部状态栏的颜色

从效果图可以看出,我们设置背景色或者背景图之后,状态栏依然还是默认的黑色,这样感觉不好看。好在,系统给我们提供了UIStatusBarStyleDefaultUIStatusBarStyleLightContent两种样式供我们选择。

UIStatusBarStyleDefault,系统的默认样式,黑色内容,用于浅色的背景(如白色)
UIStatusBarStyleLightContent 白色内容,用于深色的背景(如红色)

下面来看看具体怎么实现,主流的实现方式是分两步:

  • 在工程的Info.plist文件中添加一行UIViewControllerBasedStatusBarAppearance,选择Boolean类型,并设置为YES,Xcode会自动把名称变为View controller-based status bar appearance。

  • 在你的ViewController中添加下面的方法-(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

我们来看看运行效果。

5. 设置返回按钮的颜色-tintColor

从上面的效果图中我们可以看到返回按钮还是默认的蓝色按钮,下面我将会大家来介绍返回按钮的个性化。

self.navigationController.navigationBar.tintColor = [UIColor whiteColor];

得到的效果图如下:

6. 设置返回按钮的图片
// OC
- (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;
}
// Swift: 我这个方法运行起来侧滑并没有失效
 func creatLeftBarbuttonItem() {
        let leftButtonFrame = CGRectMake(10, 10, 20, 25)
        let leftButton = UIButton(frame: leftButtonFrame)
        leftButton.setImage(UIImage(named: "fanhuijian"), forState: .Normal)
        leftButton.addTarget(self, action: #selector(self.leftButtonPop(_:)), forControlEvents: .TouchUpInside)
        self.navigationItem.leftBarButtonItem = UIBarButtonItem(customView: leftButton)
}
    
func leftButtonPop(sender: UIButton) {
        self.navigationController?.popViewControllerAnimated(true)
}

得到的效果如下:

这里需要注意的地方有三点:

1.需要自己实现返回按钮的事件。
2.特别的解释下UIImage的*imageWithRenderingMode:*方法,参数UIImageRenderingModeAlwaysOriginal 表示总是用原图渲染,如果不这么设置,返回按钮将会显示tintColor的颜色(默认为蓝色)。UITabbarItem也存在同样地问题。
3.我们自己设置返回按钮,会导致系统的侧滑关闭效果失效。添加上面代码中最后一句代码即可修复。
7. 设置返回按钮的文字
- (void)setBackButtonTitle { 
UIBarButtonItem *leftButton = [[UIBarButtonItem alloc] initWithTitle:NSLocalizedString(@"取消", nil) style:UIBarButtonItemStylePlain target:self action:@selector(goToBack)]; 
leftButton.tintColor = [UIColor whiteColor]; 
self.navigationItem.leftBarButtonItem = leftButton;
}

得到的效果如下:

自定义返回按钮如果上面几种方式还无法满足你的要求(比如,需要同时设置返回按钮文字和图片),就需要用到UIBarButtonItem的initWithCustomView方法。

- (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基本上脱离不了上面的几种方式,大家可以参照上面返回按钮的设置方式。**

8. 隐藏导航栏底部的线条

有时候遇到一些特殊的要求,需要隐藏导航栏底部的线条。两行代码就可以做到。

  • 设置导航栏的背景图(setBackgroundImage方法)
  • 设置导航栏的shadowImage (setShadowImage方法)
// 方法一:
// OC
UINavigationBar *navigationBar = self.navigationController.navigationBar; 
//设置透明的背景图,便于识别底部线条有没有被隐藏 
[navigationBar setBackgroundImage:[[UIImage alloc] init] forBarPosition:UIBarPositionAny barMetrics:UIBarMetricsDefault];
 //此处使底部线条失效 
[navigationBar setShadowImage:[UIImage new]];
// Swift
 // 设置导航栏背景图片
   self.navigationController?.navigationBar.setBackgroundImage(UIImage(), forBarMetrics: UIBarMetrics.Default)
  // 设置导航栏阴影图片
  self.navigationController?.navigationBar.shadowImage = UIImage()

// 方法二:
// OC
UINavigationBar *navigationBar = self.navigationController.navigationBar; 
//设置透明的背景图,便于识别底部线条有没有被隐藏 
[navigationBar setBackgroundImage:[[UIImage alloc] init] forBarPosition:UIBarPositionAny barMetrics:UIBarMetricsDefault];
 //此处使底部线条失效 
   self.navigationController!.navigationBar.clipsToBounds = YES;
// Swift
 // 设置导航栏背景图片
   self.navigationController?.navigationBar.setBackgroundImage(UIImage(), forBarMetrics: UIBarMetrics.Default)
   self.navigationController!.navigationBar.clipsToBounds = true

来看看效果图:

想要知道更详细的内容可以参考这个页面:
How to hide iOS7 UINavigationBar 1px bottom line

9. 设置导航条底部线条的颜色

有了上面的基础,设置导航栏线条的颜色就变得很简单了。
首先,我做了个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

10. 在导航栏上添加多个按钮

以微信打开网页时的效果为例,效果图如下,有两个按钮:返回和关闭。

有下面两种方式可供选择,但是最终还是要用到leftBarButtonItems这个方法。**

#define UserMethod1 0
 UIBarButtonItem *closeItem = [[UIBarButtonItem alloc] initWithTitle:@"关闭" style:UIBarButtonItemStylePlain target:self action:@selector(closeAction)]; 
if (UserMethod1) { 
//方法一: 
self.navigationItem.leftBarButtonItems = @[closeItem]; 
//要求显示默认的返回按钮,但是文字会显示默认的Back,暂时还不知道这个文字怎么改 self.navigationItem.leftItemsSupplementBackButton = YES; 
} else { 
//方法二 
UIButton* leftButton = [UIButton buttonWithType:UIButtonTypeSystem]; 
leftButton.backgroundColor = [UIColor clearColor]; 
leftButton.frame = CGRectMake(0, 0, 45, 40);
 [leftButton setImage:[UIImage imageNamed:@"LeftButton_back_Icon"] forState:UIControlStateNormal];
 [leftButton setTitle:@"返回" forState:UIControlStateNormal]; 
leftButton.tintColor = [UIColor whiteColor]; 
leftButton.autoresizesSubviews = YES; 
leftButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeft; 
leftButton.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleLeftMargin;
 [leftButton addTarget:self action:@selector(goToBack) forControlEvents:UIControlEventTouchUpInside]; 
UIBarButtonItem* backItem = [[UIBarButtonItem alloc] initWithCustomView:leftButton]; 
self.navigationItem.leftBarButtonItems = @[backItem,closeItem]; 
}
Swift
    override func viewDidLoad() {
        super.viewDidLoad()
        let closeItem = UIBarButtonItem(title: "关闭", style: .Plain, target: self, action: Selector("closeAction"))
        closeItem.tintColor = UIColor.whiteColor()
        //        self.navigationItem.leftItemsSupplementBackButton = true
        let leftButton = UIButton(type: .System)
        leftButton.backgroundColor = UIColor.clearColor()
        leftButton.frame = CGRectMake(0, 0, 45, 40)
        leftButton.setImage(UIImage(named: ""), forState: .Normal)
        leftButton.setTitle("返回", forState: .Normal)
        leftButton.tintColor = UIColor.whiteColor()
        leftButton.autoresizesSubviews = true
        leftButton.contentHorizontalAlignment = .Left
        leftButton.autoresizingMask = [.FlexibleWidth, .FlexibleLeftMargin]
        leftButton.addTarget(self, action: "goToBack", forControlEvents: .TouchUpInside)
        let backItem = UIBarButtonItem(customView: leftButton)
        navigationItem.leftBarButtonItems = [backItem, closeItem]  
    }

然后,运行的效果图如下:

方法一用到了leftItemsSupplementBackButton
这个属性,会显示系统默认的返回按钮,但是文字也是显示默认的Back文字,目前还没找到怎么修改这个文字,如果有谁知道,还请不吝赐教;所以我暂时还是建议大家用方法二。相应的还有 rightBarButtonItems 这个属性,如果要在导航栏右侧展示多个按钮的话,可以设置这个属性。

11. 在导航栏上添加分段控件

这次,以QQ为例,代码如下:

UISegmentedControl *segControl = [[UISegmentedControl alloc] initWithItems:@[@"消息",@"电话"]];
 segControl.tintColor = [UIColor colorWithRed:0.07 green:0.72 blue:0.96 alpha:1]; 
[segControl setSelectedSegmentIndex:0]; 
self.navigationItem.titleView = segControl;

代码很简单,就是设置titleView
这个属性,当然,你也可以把这个属性设置为你自定义的View。

12. 导航栏全局属性设置
//全局设置导航栏主题
- (void)setNavigationControllerAppearance { 
[UINavigationBar appearance].barStyle = UIBarStyleBlack; 
[[UINavigationBar appearance] setBarTintColor:[UIColor colorWithWhite:0.1 alpha:0.5]];
 [[UINavigationBar appearance] setTintColor:[UIColor whiteColor]];}

全局设置导航栏的好处有两个:

一是不用对每个NavigationBar进行设置;
二是方便做主题管理,切换主题,只需要更改全局设置即可。
13. 与导航栏相关的一些开源组件
13.1 NJKWebViewProgress - 类似于Safiri加载网页时的进度显示
13.2 FDFullscreenPopGesture - 一个丝滑的全屏滑动返回手势

对应的文章介绍可以点这个链接

最后,奉上Demo的地址:NavigationBarDemo
文/落羽生(简书作者)原文链接:http://www.jianshu.com/p/f0d3df54baa6

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,390评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,821评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,632评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,170评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,033评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,098评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,511评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,204评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,479评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,572评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,341评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,213评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,576评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,893评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,171评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,486评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,676评论 2 335

推荐阅读更多精彩内容

  • UINavigationBar是我们在开发过程中经常要用到的一个控件,下面我会为大家介绍一些常用的用法。 1. 设...
    橙娃阅读 672评论 0 1
  • UINavigationBar是我们在开发过程中经常要用到的一个控件,下面我会为大家介绍一些常用的用法。 1. 设...
    lexiaoyao20阅读 61,457评论 35 302
  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 11,943评论 4 60
  • 『一二三四,坚持下去,在一分钟就结束了』 『我知道你肌肉很酸,代表你的身体在接受力量了,很好,加油』 每次上有氧课...
    DaiWanDouLi阅读 341评论 0 1
  • 在正式公布“SS17正式退役“消息的前几天。 我还是不习惯,尽管我已经相信你的梦想已经从生活里慢慢消失了。我看着手...
    修天丰阅读 738评论 3 4