iOS 一种新的修改导航栏样式的方法.
开宗明义:
对系统导航栏最底层的UIView加一层CALayer, 通过操作这个自己创建的CALayer来修改导航栏样式.
修改系统导航栏样式的几种方法
- 1.使用系统的API, 更换导航栏背景图片
[[UINavigationBar appearance] setBackgroundImage:[UIImage imageNamed:@"nav_bg.png"] forBarMetrics:UIBarMetricsDefault];
//或者
[self.navigationController.navigationBar setBackgroundImage:[UIImage imageNamed:@"m_nav"] forBarMetrics:UIBarMetricsDefault];
self.navigationBar.layer.masksToBounds = YES;
优点: 找UI出图就好了.
缺点: 如果项目中导航栏样式需要经常变化, 这样的方式就很麻烦了.需要考虑push和pop的情况. 所以在每个控制器中viewWillAppear和viewDisAppear中都需要写导航栏样式的代码. 而且没办法实现类似QQ中, 滑动时导航栏颜色渐变的效果.
- 2.在导航栏中加一层UIView.
缺点: 导航栏中插入一层UIView后, 系统提供的侧滑返回手势失效. 系统的返回按钮不可点击.
一种新的想法
第一种方法, 更换导航栏背景图片应该是应用最多的方法. 但是在系统更新到iOS10之后. 写了self.navigationBar.layer.masksToBounds = YES.之后会发现导航栏最上方状态栏的位置, 颜色设置失效了.
观察发现苹果在iOS10 的SDK中对导航控制器添加了许多新的API. 可能在增加这些API的同时, 也对导航控制器的机制做了一些修改.
我的手机更新到iOS10之后发现几个大厂出的app导航栏也出了问题...
处理导航栏问题. 最根本的办法还是全部自定义.但是自定义写起来实在太过麻烦. 最好还是能在系统导航栏的基础上做简单修改实现我们想要的效果.
为此我想到的办法是在系统导航栏的各个层次中找到最底层的UIView. 对这一层UIView添加一层CALayer. 首先保证导航栏中其他的UIView全部是透明的. 然后通过操作这个我们创建的CGLayer来达到控制导航栏样式的目的.
经过我的实验发现添加CALayer不会影响系统的返回按钮和系统的侧滑返回手势(话说这个返回手势做的确实很好用, 很舒服.).
步骤.
- 将导航栏的Translate属性设置为YES.
- 在NavigationController中的ViewDidLoad方法中遍历当前View的SubView找到数组的"0"号元素.(iOS9的SDK中提供了拿到最底层view的API. 但是app需要支持iOS8. 不能使用这个API.)
- 创建一个CALayer.将这个CALayer添加到"0"号元素(它是一个UIView)subLayer中.
- 将导航栏中的所有的UIView设置为透明.(用文章开始的第一种方法, 设置透明图片).
over. 以后需要设置导航栏颜色, 就对这个CALayer设置颜色即可. 还可以通过操作CALayer实现导航栏颜色渐变等效果.
代码.
我的项目中导航栏样式会发生多次变化. 所以对导航栏使用上面的方法进行了一些简单封装.
使用方法. 初始化navigationController之后通过接口给导航栏初始的样式. 以后如果需要修改导航栏样式就在push之前修改样式即可.
代码链接.
https://github.com/ddyd369/ZDNavigationController
转发请注明出处(简书 行如风).