原文网址:http://www.jianshu.com/p/f0d3df54baa6

UINavigationBar是我们在开发过程中经常要用到的一个控件,下面我会为大家介绍一些常用的用法。

1. 设置导航栏的标题

这个不多说,直接上代码
self.navigationItem.title = @"UINavigationBar使用总结";

2. 设置导航栏的背景颜色

//通过barTintColor来设置背景色
self.navigationController.navigationBar.barTintColor = [UIColor redColor];

得到的效果如下:

Snip20150912_1.png

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

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

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

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

Snip20150912_2.png

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

//表示横屏竖屏都显示
UIBarMetricsDefault,
//表示在只横屏下才显示,和UIBarMetricsLandscapePhone功效一样,不过iOS8已经弃用了
UIBarMetricsCompact,
UIBarMetricsDefaultPrompt和UIBarMetricsCompactPrompt这两个我还没搞清楚是什么意思,有知道的朋友不妨给我们来普及一下。。

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

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

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

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

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

    Snip20150913_4.png
  2. 在你的ViewController中添加下面的方法
    -(UIStatusBarStyle)preferredStatusBarStyle{
    return UIStatusBarStyleLightContent;
    }

想知道更多地方式,可以参考这两个页面:How to change Status Bar text color in iOS 7iOS7下Status Bar字体颜色修改

另外,特别需要注意的是,如果你的ViewController是通过navigationController push进来的,还需要加下面一句代码才能生效:
self.navigationController.navigationBar.barStyle = UIBarStyleBlack;
具体,可参考UIStatusBarStyle PreferredStatusBarStyle does not work on iOS 7

恩,我们来看看运行效果。

Snip20150913_5.png

5. 设置返回按钮

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

  • 设置返回按钮的颜色
    只需要设置tintColor属性即可

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

    得到的效果图如下:

    Snip20150915_1.png
  • 只设置返回按钮的图片
- (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;
}

得到的效果如下:

Snip20150915_2.png

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

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

得到的效果如下:

Snip20150915_3.png
  • 自定义返回按钮
    如果上面几种方式还无法满足你的要求(比如,需要同时设置返回按钮文字和图片),就需要用到UIBarButtonIteminitWithCustomView方法。
- (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;
}

得到的效果图如下:

Snip20150915_5.png

设置rightBarButtonItem基本上脱离不了上面的几种方式,大家可以参照上面返回按钮的设置方式。

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

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

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

来看看效果图:

Snip20150922_1.png

另外,还有一种做法,一行代码就可以达到效果,也真是够神奇的。。

//方法二:
self.navigationController.navigationBar.clipsToBounds = YES;

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

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

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

依照惯例,看下效果图:

Snip20150923_2.png

当然还有其他的方式也可以做到,如addSubview, addSubLayer等。感兴趣的话可以参考下这个页面:iOS7 - Change UINavigationBar border color

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

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

微信效果图.png

有下面两种方式可供选择,但是最终还是要用到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];
}

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

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

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

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

这次,以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。

类似于QQ的导航栏.png

10. 导航栏全局属性设置

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

全局设置导航栏的好处有两个:一是不用对每个NavigationBar进行设置;二是方便做主题管理,切换主题,只需要更改全局设置即可。

11. 与导航栏相关的一些开源组件

11.1 NJKWebViewProgress - 类似于Safiri加载网页时的进度显示

网页加载进度.png

11.2 FDFullscreenPopGesture - 一个丝滑的全屏滑动返回手势

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

丝滑的全屏返回手势.png

最后,奉上Demo的地址:NavigationBarDemo

文/落羽生(简书作者)
原文链接:http://www.jianshu.com/p/f0d3df54baa6
著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。

【转】UINavigationBar 使用总结的更多相关文章

  1. iOS阶段学习第31天笔记(UINavigationBar介绍)

    iOS学习(UI)知识点整理 一.UINavigationBar 的介绍 1)概念:UINavigationBar 是用于定义导航栏按钮的一个类对象 2)在使用UINavigationBar之前必须先 ...

  2. UINavigationItem UINavigationBar 关系分析

    目录 1.关系分析 2.关系综述 3.概念点 4.疑问 1.关系分析 UIBarItem-> UIBarButtonItem -> UINavigationItem 1.1 UIBarIt ...

  3. UINavigationItem UINavigationBar 关系分析[转]

    http://blog.csdn.net/luoyeffcs/article/details/16106707 目录 1.关系分析 2.关系综述 3.概念点 4.疑问 1.关系分析 UIBarItem ...

  4. iOS开发备忘录:自定义UINavigationBar背景图片和Back按钮

    iOS项目,根据设计图,有时需要自定义UIView的UINavigationBar的背景.可以切出来一张1像素左右的背景图片,来充当UINavigationBar的背景. 可以利用Navigation ...

  5. UITabBar,UINavigationBar的布局和隐藏问题

    ---恢复内容开始--- 1. 前言 UITabBar,UINavigationBar非常的好用,但是毕竟是系统自带的,不受自己完全掌握,对于布局和隐藏会有一些问题,现在就来谈谈我的想法和一些问题. ...

  6. UINavigationBar 和 UINavigationItem的属性设置

    #import "RootViewController.h" @interface RootViewController () @end @implementation RootV ...

  7. IOS 入门开发之创建标题栏UINavigationBar的使用(二)

    IOS 入门开发之创建标题栏UINavigationBar的使用 http://xys289187120.blog.51cto.com/3361352/685746     IOS 开发有关界面的东西 ...

  8. iOS7中如何去除UINavigationbar下边的那条黑线

    做项目过程中遇到要去掉导航栏下面的一条黑线,从网上找到的一个方法 默认UINavigationbar样式 准备用于替换的背景 替换后的效果 if ([self.navigationController ...

  9. ios7 自定义UINavigationBar UIBarButtonItem 10px的偏移纠正

    为UINavigationBar 写一个分类.UINavigationItem+correct_offset.h  转载 http://www.colabug.com/thread-1112420-1 ...

  10. iOS 开发 中级:UIToolbar,UINavigationBar,UITabBar,UIBarButtonItem,UITabBarItem自定义方法总结

    原文:  http://blog.csdn.net/songrotek/article/details/8692866?utm_source=tuicool 对于UIToolbar,UINavigat ...

随机推荐

  1. Kinetic使用注意点--container

    <virtual> new Container(config) 参数: config:包含所有配置项的对象. { x: "横坐标", y: "纵坐标" ...

  2. ExtJs 4.2 treePanel 点击树节点 传送参数到后台(多个参数)

    //***********************************************左边树开始********************************************** ...

  3. EXTJS 4.2 资料 控件lable定义

    代码: { xtype:'label', id:'label', labelSeparator :'', // 去掉laebl中的冒号 fieldLabel : '这是个label' } 赋值: Ex ...

  4. 【tyvj1860】后缀数组

    描述 我们定义一个字符串的后缀suffix(i)表示从s[i]到s[length(s)]这段子串.后缀数组(Suffix array)SA[i]中存放着一个排列,满足suffix(sa[i])< ...

  5. 微软职位内部推荐-SDE

    微软近期Open的职位: Organization Summary:Engineering, Community & Online (ECO) is looking for a great & ...

  6. python学习笔记19(序列的方法)

    序列包含有宝值 表(tuple)和表(list).此外,字符串(string)是一种特殊的定值表,表的元素可以更改,定值表一旦建立,其元素不可更改. 任何的序列都可以引用其中的元素(item). 下面 ...

  7. ajax 获取 mysql 保存的图片显示

    function ajax_GetFirstData(data) { var len = data.Data.length; if (len > 0) { $("#jquery_jpl ...

  8. bnuoj 4357 传送阵

    http://www.bnuoj.com/bnuoj/problem_show.php?pid=4357 [题意]:在1000个数中选择3个之和是m的倍数,可能有多种选择方案,请输出标号排序最小的一组 ...

  9. 简单的SQL Server在线查看和执行系统

    在大的公司里面,往往数据库和表都非常的多,一张表的字段也是会有几十个.如果这么多的表和字段没有说明注释的话,查看起来会一头雾水,新来的或者别的部门的同事看到表和字段会完全不知道是干嘛的,只能靠名称来猜 ...

  10. 一个简单的js计数器(web储存)。

    <span id="countspan"></span> <a href="#" onclick="countNumbe ...