iOS 13 客製 bar 模樣的 UINavigationBarAppearance
請參考以下新版說明的連結,原本文章的內容是舊版的說明。
新版說明
舊版說明
iOS 13 的 navigation bar 多了一些新的樣式設定方法,多了方便我們客製它模樣的新類別, UINavigationBarAppearance ,接下來就讓我們好好認識它的威力吧。
預設的 navigation bar 樣式
我們先在 storyboard 上建立一個 navigation controller,串接兩個畫面,顯示伊坂幸太郎的新書,蹺蹺板怪物。
App 啟動後, navigation bar 將呈現毛玻璃的效果,隱隱約約看到背後 view 的顏色。
透明的 navigation bar
現在讓我們透過 UINavigationBarAppearance,將 navigation bar 變透明吧。
override func viewDidLoad() {
super.viewDidLoad()
let barAppearance = UINavigationBarAppearance()
barAppearance.configureWithTransparentBackground()
navigationController?.navigationBar.standardAppearance = barAppearance
}
產生 UINavigationBarAppearance 物件 barAppearance 後,呼叫 function configureWithTransparentBackground 將 bar 變透明, 然後將 barAppearance 設為目前畫面 navigationBar 的 standardAppearance。
透過同樣的方法,我們也可以讓搭配捲動畫面的 navigation bar 變透明,比方以下搭配 table view 的 navigation bar。
如下圖所示,我們將 table 的背景設為綠色,因此當 navigation bar 透明時,我們將清楚看到表格的背景色。
讓整個 App 的 navigation bar 變透明
在類別 AppDelegate 的 function application(_:didFinishLaunchingWithOptions:)裡產生 UINavigationBarAppearance 物件,然後將它設為 UINavigationBar.appearance() 的 standardAppearance。
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
let barAppearance = UINavigationBarAppearance()
barAppearance.configureWithTransparentBackground() UINavigationBar.appearance().standardAppearance = barAppearance
return true
}
指定 navigation bar 的顏色
當我們設定 UINavigationBarAppearance 的 backgroundColor 時,navigation bar 將變成完全不透明,顯示我們指定的顏色。
let barAppearance = UINavigationBarAppearance()
barAppearance.backgroundColor = .red
預設透明的放大版 navigation bar
若是放大版的 navigation bar,navigation bar 將預設變成透明的樣式。
若想讓放大版的 navigation bar 顯示毛玻璃效果,則須呼叫 function configureWithDefaultBackground,然後設定 scrollEdgeAppearance。
let barAppearance = UINavigationBarAppearance()
barAppearance.configureWithDefaultBackground()
UINavigationBar.appearance().scrollEdgeAppearance = barAppearance
搭配捲動畫面的放大版 navigation bar
當放大版的 navigation bar 搭配捲動畫面,比方搭配 table 時,navigation bar 將預設變成透明的樣式,捲動後顯示毛玻璃的 bar。
如下圖所示, table 的背景為綠色,因此一開始 navigation bar 透明時將看到清楚的綠色。接著當 table 捲動時,它將變身成毛玻璃的樣式和背景顏色融合在一起。
我們也可以讓 navigation bar 一開始就顯示毛玻璃效果,透過呼叫 function configureWithDefaultBackground,然後設定 scrollEdgeAppearance。
let barAppearance = UINavigationBarAppearance()
barAppearance.configureWithDefaultBackground()
UINavigationBar.appearance().scrollEdgeAppearance = barAppearance
搭配放大版的 navigation bar 時,scrollEdgeAppearance 控制一開始的 bar 樣式,standardAppearance 則控制向上捲動時的樣式,因此若是我們只設定 scrollEdgeAppearance 顯示紅色 bar,向上捲動時 bar 將變回灰色樣式。
let barAppearance = UINavigationBarAppearance()
barAppearance.backgroundColor = .red
UINavigationBar.appearance().scrollEdgeAppearance = barAppearance
我們也可以設計兩種樣式, scrollEdgeAppearance 顯示紅色 bar,standardAppearance 顯示黃色 bar。因此一開始會顯示紅色,向上捲動時會顯示黃色。
let scrollEdgeAppearance = UINavigationBarAppearance()
scrollEdgeAppearance.backgroundColor = .red
UINavigationBar.appearance().scrollEdgeAppearance = scrollEdgeAppearance
let standardAppearance = UINavigationBarAppearance()
standardAppearance.backgroundColor = .yellow
UINavigationBar.appearance().standardAppearance = standardAppearance
指定特定頁面的 navigation bar 樣式
我們也可以從 controller 的 navigationItem 設定UINavigationBarAppearance,如此將只影響此頁面的 bar 樣式。
let barAppearance = UINavigationBarAppearance()
barAppearance.configureWithDefaultBackground()
navigationItem.standardAppearance = barAppearance
navigation bar 的背景圖片
UINavigationBarAppearance 的 backgroundImage 控制 navigation bar 的背景圖片。
let barAppearance = UINavigationBarAppearance()
barAppearance.backgroundImage = UIImage(named: "bar")
navigation bar 的 shadow
let barAppearance = UINavigationBarAppearance() barAppearance.shadowColor = nil
我們可透過 shadowColor 設定 navigation bar 下方 shadow 的顏色,比方左下是預設的 shadow,右下是 shadowColor 設為 nil 後無 shadow 的模樣。
back button 的圖片
我們也可以改變 back button 的圖片,比方以下例子透過 function setBackIndicatorImage(_:transitionMaskImage:) 設定 back button 的圖片。
let barAppearance = UINavigationBarAppearance()
let backIndicatorImage = UIImage(systemName: "arrowshape.turn.up.left.fill")
barAppearance.setBackIndicatorImage(backIndicatorImage, transitionMaskImage: backIndicatorImage)
setBackIndicatorImage 的宣告如下,我們通常將 backIndicatorImage & transitionMaskImage 設為一樣的圖片。
open func setBackIndicatorImage(_ backIndicatorImage: UIImage?, transitionMaskImage backIndicatorTransitionMaskImage: UIImage?)
button item 的樣式
利用 UIBarButtonItemAppearance 設定 button item 的樣式,然後將它存入 UINavigationBarAppearance 的 buttonAppearance。(也可以設定 backButtonAppearance 或 doneButtonAppearance)
let barAppearance = UINavigationBarAppearance()barAppearance.configureWithTransparentBackground()let buttonAppearance = UIBarButtonItemAppearance(style: .plain)buttonAppearance.normal.titleTextAttributes = [.foregroundColor: UIColor.red]barAppearance.buttonAppearance = buttonAppearance
navigation bar 的標題樣式
利用 titleTextAttributes 設定 navigation bar 的標題樣式,largeTitleTextAttributes 設定放大版 bar 的標題樣式。
let barAppearance = UINavigationBarAppearance()
barAppearance.titleTextAttributes = [.foregroundColor: UIColor.red, .font: UIFont.systemFont(ofSize: 20)]