iOS一种新的修改导航栏样式的方法

goldenswan 发布于2年前
0 条问题

开宗明义: 对系统导航栏最底层的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不会影响系统的返回按钮和系统的侧滑返回手势(话说这个返回手势做的确实很好用, 很舒服.).

步骤.

  1. 将导航栏的Translate属性设置为YES.
  2. 在NavigationController中的ViewDidLoad方法中遍历当前View的SubView找到数组的"0"号元素.(iOS9的SDK中提供了拿到最底层view的API. 但是app需要支持iOS8. 不能使用这个API.)
  3. 创建一个CALayer.将这个CALayer添加到"0"号元素(它是一个UIView)subLayer中.
  4. 将导航栏中的所有的UIView设置为透明.(用文章开始的第一种方法, 设置透明图片). 
    over. 以后需要设置导航栏颜色, 就对这个CALayer设置颜色即可. 还可以通过操作CALayer实现导航栏颜色渐变等效果.

代码.

我的项目中导航栏样式会发生多次变化. 所以对导航栏使用上面的方法进行了一些简单封装.

使用方法. 初始化navigationController之后通过接口给导航栏初始的样式. 以后如果需要修改导航栏样式就在push之前修改样式即可.

代码链接.

https://github.com/ddyd369/ZDNavigationController

需要 登录 后回复方可回复, 如果你还没有账号你可以 注册 一个帐号。