前言:经常遇到这样的需求:从有导航栏的界面跳转到导航栏透明的界面,由于iOS从有导航栏跳转到透明导航栏界面,并且设置hideBottomWhenPush属性会有bug,即导航栏会有黑影。我采取将导航栏控制的navigationbar进行隐藏,自己在viewcontroller添加一个navigationbar以实现需求。过程中没有理解清楚navigationbar和navigationItem,这里简单记录一下。

The navigation bar displays information from a stack of UINavigationItem objects. At any given time, the UINavigationItem that is currently the topItem of the stack determines the title and other optional information in the navigation bar, such as the right button and prompt.

翻译:navigationbar 展示通过一个栈对象navgationItem来展示信息,栈顶的navgationItem对象决定着导航标题和其他信息,例如导航栏右边提示按钮。

这里可以得知如果想管理navigationbar上面的左右按钮,标题信息,则需要创建一个navigationItem对象,对navigationItem进行设置后再push,pop等操作进入到navigationbar的栈中。而如果管理样式,则通过属性控制或者修改子控件。navigationbar的层级结构如下:
navigationbar层级结构.png

Paste_Image.png

结构中看出:
默认navigationbar高度为44点,但navigationbar的View却有84点的高度,iOS7以后对背景进行了延伸。View中有背景图View、底部线条View还有图中红色框部分的按钮等控件。设置导航栏透明经常对背景图与底部线条设置为透明的图片。

navigationController下默认有一个navigationBar,这是navigationController管理下所有viewcontroller共用的。对于某个页面设置导航栏透明,滑动渐变效果,可以让navigationController的隐藏掉,自己给每个viewcontroller增加一个navigationBar,对这个navigationBar进行处理。退出界面后将导航栏恢复显示。这个方案也是上面推荐链接一个方案之一。这样可以避免一些因为设置导航栏透明,在界面中跳转带来的系统bug。

NavigationItem属性.png
NavigationItem是UIViewController的属性,这也是导航器管理下的viewcontroller中进行设置的原因:

1
self.navigationItem.title = @"title";

而不是

1
self.navigationController.navigationItem.title = @"title";

思考了一下navigationItem为什么是viewcontroller的属性,而不是navigationbar的属性呢?因为navigationbar是栈的方式管理navigationItem。navigationcontroller每次push或者pop一个viewcontroller,其实也执行了对navigationbar执行了push or pop item。这样每个viewcontroller拥有自己的navigationItem,则可以订制自己的页面导航栏。

相关链接

1.http://www.jianshu.com/p/e3ca1b7b6cec