iOS 導航欄的控制

SSBun發表於2017-12-13

顏色

導航條的屬性 translucent 可以控制導航條是否是透明的, 預設是YES,也就是透明的。開啟時透過導航條可以模糊的看到ViewController或是Window的背景圖案。這裡我們分為兩種情況來討論背景顏色的設定

在關閉translucent的情況下 可以通過 barTintColor 來設定導航條的背景色 當然也可以通過 setBackgroundImage 來設定背景 但是backgroundImage的圖層更靠上一些,也就是說如果兩個都設定的話,顯示的是backgroundImage的圖片,不過如果你的圖片如果有透明的話,也會透出barTintColor的顏色

如果backgroundImage設定為純透明色,tintColor也設定為純透明色的話,這個時候導航條是黑色的,這個時候不能透出window的背景色或是viewController的顏色,並且,此時設定bar的backgroundColor 是沒有用的

在開啟 translucent 的情況下 幾乎一樣,不過是在兩個圖層下面又可以透出Window或是viewController的背景色 如果backgroundImage設定為純透明色,tintColor也設定為純透明色的話,此時設定bar的backgroundColor 只會改變導航條的顏色,狀態列則會透視下去,顯示的是viewController或是window的背景顏色

設定分割線的顏色需要使用 shadowImage 屬性,你可以賦予一張圖片,但是這個圖片只有在導航條背景使用 setBackgrounImage 設定的時候才能預設啟用,否則是沒有用的

這裡你可以這樣認為, backgroundImage在第一層, barTintColor在第二層,translucent是第三層(YES的時候是模糊透明,NO的時候是黑色不透明的), backgroundColor是第四層(但是隻能顯示bar的44點高度的顏色,不能影響到status的顏色),通過層級,你就可以自由的控制你想要的效果了。

顯示和隱藏

導航條的隱藏和顯示可以通過navigationBar.hidden控制

statusBar 顯示和隱藏

如果 View controller-based status bar appearance 為 NO, 我們就只能使用全域性控制。就是使用 UIApplication.sharedApplication.statusBarHidden 來控制,但是這裡蘋果已經不推薦了,因為一個地方的改動會影響整個應用

  • 沒用使用導航管理控制器時 通過重寫方法**-(BOOL)prefersStatusBarHidden來實現隱藏和顯示statusBar 通過重寫方法- (UIStatusBarAnimation)preferredStatusBarUpdateAnimation** 來控制狀態列顯示動畫 通過重寫方法**- (UIStatusBarAnimation)preferredStatusBarStyle** 來控制狀態列樣式

  • 使用導航來管理控制器時 這個時候以上各個屬性並不會被呼叫,我們需要實現一個導航控制器的子類,然後在實現中覆寫方法 -(UIViewController )childViewControllerForStatusBarHidden - (UIViewController )childViewControllerForStatusBarStyle 通過它返回你要控制的控制器就ok了,一般是返回self.topViewController**

可能遇見的問題

重寫的方法不執行(實現了導航控制器子類後還是不執行) 如果你從vcA使用present的方式跳轉到vcB,並且使用自定義動畫(UIViewControllerAnimatedTransitioning),上述方法也是不會執行的。解決方法是在vcB初始化的時候把 modalPresentationCapturesStatusBarAppearance設為 true。這個屬性決定vcB在非全屏模式下被present時,是否接管statusBar外觀的控制權,預設為NO。因為自定義動畫屬於非全屏的跳轉,所以跳轉以後的vc並沒有獲得statusBar外觀的控制權,上面的方法就失效了,

push的時候導航條會黑一下 一般是你實現一個導航控制器的子類,並用它push控制器的時候發生,可能是因為轉場動畫containerView的背景色的問題,你可以在導航控制器中設定自己的背景色是白色,就ok了

class ViewController: UIViewController { var isHidden:Bool = false @IBAction func clicked(sender: AnyObject) { isHidden = !isHidden UIView.animateWithDuration(0.5) { () -> Void in self.setNeedsStatusBarAppearanceUpdate() } } override func preferredStatusBarUpdateAnimation() -> UIStatusBarAnimation { return UIStatusBarAnimation.Slide } override func prefersStatusBarHidden() -> Bool { return isHidden } }

相關文章