問題描述
App 開發中,有時候需要改變導航欄或者狀態欄背景色、字體顏色,或者實現導航欄背景色漸變效果,那么,接下來的部分為你解答,請看下文!
自定義狀態欄
狀態欄字體默認是黑色,修改成白色,需要設置兩個地方,如下所示:
第一步:工程配置文件 plist 中添加 View controller-based status bar appearance ,狀態值設置為 NO,Source Code 如下:
<key>UIViewControllerBasedStatusBarAppearance</key>
<false/>
第二步:設置 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
效果圖如下:
導航欄設置圖片
導航欄設置背景圖片,只能顯示純色圖片,如果其他控制器中修改導航欄背景,會影響到之前的設置,代碼如下:
self.navigationBar.backgroundColor = UIColor.clear
self.navigationBar.barTintColor = UIColor.clear
// 主要是下面這句,上面兩句主要是防止干擾
self.navigationBar.setBackgroundImage(UIImage(named: "xxxxxx"), for: .default)
效果圖如下:
注意:如果代碼中有如下設置,會使導航欄設置的圖片失效,代碼如下:
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
效果圖如下:
特別強調:如果我們把注釋掉的代碼和相應的代碼替換,會導致導航欄在 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 到子控制器,就會導致子控制器中的導航欄標題和返回按鈕顯示不出來,對應的效果如下:
所以我們需要將自定義 layer 添加到 self.navigationBar.subviews.first 對應的 layer 中,具體原因可能和導航欄的圖層有關,正確的效果圖如下:
視圖層級調試
介紹
Debug View Hierarchy(視圖層級調試)是 XCode 6 新出的一項功能,它可以讓開發者在程序運行時,動態的查看當前界面的顯示情況,包括視圖的層次,控件的大小和位置,而且會以 3D 效果顯示當前視圖的層次。
使用
上面 為什么將自定義 layer 添加到 self.navigationBar.subviews.first 對應的 layer 中,正式根據 視圖層級調試 模式得出來的。具體使用如下圖所示:
運行程序進入視圖層級調試模式:
查看視圖層級關系: