Swift自定义UINavigationBar样式

问题描述

App 开发中,有时候需要改变导航栏或者状态栏背景色、字体颜色,或者实现导航栏背景色渐变效果,那么,接下来的部分为你解答,请看下文!

自定义状态栏

状态栏字体默认是黑色,修改成白色,需要设置两个地方,如下所示:

第一步:工程配置文件 plist 中添加 View controller-based status bar appearance ,状态值设置为 NO,Source Code 如下:

UIViewControllerBasedStatusBarAppearance

第二步:设置 UIApplication 对象,可以在 AppDelegate 或者 导航控制器中设置,或者你需要改变的控制器中设置,如下所示:

// default 默认黑色 lightContent 白色
UIApplication.shared.statusBarStyle = .lightContent

自定义导航栏

导航栏设置颜色

导航栏设置字体颜色和大小,需要设置 titleTextAttributes 属性,背景色需要设置 barTintColor 属性,如下所示:

let attributes = [
    NSForegroundColorAttributeName : UIColor.blue,
    NSFontAttributeName: UIFont.systemFont(ofSize: 18)]
// 设置导航栏 字体 为 蓝色, 字体 大小 为 18 号字体
UINavigationBar.appearance().titleTextAttributes = attributes

// 设置导航栏 背景 为 红色
UINavigationBar.appearance().barTintColor = UIColor.red

效果图如下:

Swift自定义UINavigationBar样式_第1张图片
导航栏效果图.png

导航栏设置图片

导航栏设置背景图片,只能显示纯色图片,如果其他控制器中修改导航栏背景,会影响到之前的设置,代码如下:

self.navigationBar.backgroundColor = UIColor.clear
self.navigationBar.barTintColor = UIColor.clear
// 主要是下面这句,上面两句主要是防止干扰
self.navigationBar.setBackgroundImage(UIImage(named: "xxxxxx"), for: .default)

效果图如下:

Swift自定义UINavigationBar样式_第2张图片
导航栏设置图片效果图.png

注意:如果代码中有如下设置,会使导航栏设置的图片失效,代码如下:

if #available(iOS 9.0, *) {
    navigationController?.navigationBar.subviews[0].subviews[0].isHidden = true;
} else {
    navigationController?.navigationBar.subviews[0].subviews[1].isHidden = true;
}

导航栏设置渐变色

导航栏设置渐变色需要用到 CAGradientLayer 类,具体代码如下:

let gradientLayer = CAGradientLayer()
let startColor = UIColor.red
let endColor = UIColor.yellow
gradientLayer.colors = [startColor.cgColor, endColor.cgColor]
gradientLayer.locations = [0.3, 0.7]
gradientLayer.startPoint = CGPoint(x: 0, y: 0)
gradientLayer.endPoint = CGPoint(x: 1.0, y: 0)

// gradientLayer.frame = CGRect(x: 0, y: -20.0, width: self.view.width, height: 64.0)
gradientLayer.frame = CGRect(x: 0, y: 0, width: self.view.width, height: 64.0)

self.navigationBar.isTranslucent = false

// self.navigationBar.layer.addSublayer(gradientLayer)
if let barBackground = self.navigationBar.subviews.first {
  
    barBackground.layer.insertSublayer(gradientLayer, at: 0)
}

注意:其中 isTranslucent 属性的使用,可以参考下面这篇文章:
http://www.cnblogs.com/gfxxbk/p/5999663.html

效果图如下:

Swift自定义UINavigationBar样式_第3张图片
导航栏设置渐变色效果图.png

特别强调:如果我们把注释掉的代码和相应的代码替换,会导致导航栏在 push 或者 pop 的过程中,导航栏标题和返回按钮不显示,如下所示:

let gradientLayer = CAGradientLayer()
let startColor = UIColor.red
let endColor = UIColor.yellow
gradientLayer.colors = [startColor.cgColor, endColor.cgColor]
gradientLayer.locations = [0.3, 0.7]
gradientLayer.startPoint = CGPoint(x: 0, y: 0)
gradientLayer.endPoint = CGPoint(x: 1.0, y: 0)

gradientLayer.frame = CGRect(x: 0, y: -20.0, width: self.view.width, height: 64.0)
// gradientLayer.frame = CGRect(x: 0, y: 0.0, width: self.view.width, height: 64.0)

self.navigationBar.isTranslucent = false

self.navigationBar.layer.addSublayer(gradientLayer)

// if let barBackground = self.navigationBar.subviews.first {
//
// barBackground.layer.insertSublayer(gradientLayer, at: 0)
// }

当 push 到子控制器,就会导致子控制器中的导航栏标题和返回按钮显示不出来,对应的效果如下:

Swift自定义UINavigationBar样式_第4张图片
导航栏设置渐变色效果图-1.png

所以我们需要将自定义 layer 添加到 self.navigationBar.subviews.first 对应的 layer 中,具体原因可能和导航栏的图层有关,正确的效果图如下:

Swift自定义UINavigationBar样式_第5张图片
导航栏设置渐变色效果图-2.png

视图层级调试

介绍

Debug View Hierarchy(视图层级调试)是 XCode 6 新出的一项功能,它可以让开发者在程序运行时,动态的查看当前界面的显示情况,包括视图的层次,控件的大小和位置,而且会以 3D 效果显示当前视图的层次。

使用

上面 为什么将自定义 layer 添加到 self.navigationBar.subviews.first 对应的 layer 中,正式根据 视图层级调试 模式得出来的。具体使用如下图所示:

运行程序进入视图层级调试模式:

Swift自定义UINavigationBar样式_第6张图片
层级图演示步骤-1.png

查看视图层级关系:

Swift自定义UINavigationBar样式_第7张图片
层级图演示步骤-2.png

原文链接:http://sessionch.com/ios/ios-navigationbar-custom.html

你可能感兴趣的:(Swift自定义UINavigationBar样式)