隨便打開手機上的主流APP,我們不難發現它們的狀態欄都是跟導航欄保持一致的背景顏色,如下圖的微信和instagram:
WECHAT.PNG
INS.PNG
那么今天我們就來說一下StatusBar這個只有區區20像素高度的小東西。
UIStatusBarStyle
狀態欄有兩種顯示風格:
1.UIStatusBarStyleDefault
2.UIStatusBarStyleLightContent
那么它的背景顏色是怎么加上去的呢?很簡單,看代碼:
UIView *statusBar = [[UIView alloc] initWithFrame:CGRectMake(0, -20, self.view.frame.size.width, 20)];
statusBar.backgroundColor = myColor;
[self.navigationController.navigationBar addSubview:statusBar];
看完代碼就知道沒什么可說的了。
要改變狀態欄的顯示樣式(前景顏色)需要在ViewContoller里重載方法:
- (UIStatusBarStyle)preferredStatusBarStyle
{
return UIStatusBarStyleLightContent;
}
但是上面這個方法不能直接調用,需要通過下面這個方法來刷新狀態欄的樣式,例如:
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[self setNeedsStatusBarAppearanceUpdate];
}
如果你按照上面說的,在自己的ViewController里面設置一番之后,運行發現你的狀態欄還是默認狀態...那就對了,因為遠沒有那么容易。你還需要耐心往下看...
UIViewControllerBasedStatusBarAppearance
在info.plist中可以設置狀態欄的外觀是否是基于視圖控制器,鍵的名稱就是UIViewControllerBasedStatusBarAppearance,如果不設置那么它的默認值是YES,表示視圖控制器決定了狀態欄的風格;如果值設置為NO,則表示每個視圖控制器必須顯式地使用UIApplication對象來設置狀態欄的風格。
哎~這個時候你肯定會疑惑了,我按照你上面說的沒有設置plist文件啊,所以默認是YES,那么就是由視圖控制器來決定狀態欄風格啊,為什么不對呢?
childViewControllerForStatusBarStyle
當我們調用setNeedsStatusBarAppearanceUpdate時,系統會調用application.window.rootViewController的preferredStatusBarStyle方法,而不是當前控制器的preferredStatusBarStyle方法。在這個時候,一個重要的方法就要派上用場了,那就是:childViewControllerForStatusBarStyle。
childViewControllerForStatusBarStyle默認返回nil。所以我們需要重寫這個方法。
假設你的APP里根視圖是導航控制器:
self.window.rootViewController = [[UINavigationController alloc] initWithRootViewController:viewVontroller];
那么,我們子類化一個導航控制器ZXNavigationController,重寫它的childViewControllerForStatusBarStyle方法:
@implementation ZXNavigationController
- (UIViewController *)childViewControllerForStatusBarStyle
{
return self.topViewController;
}
- (void)viewDidLoad {
[super viewDidLoad];
}
上面代碼的意思就是說,不要調用我自己也就是UINavigationController的preferredStatusBarStyle方法,而是去調用navigationController.topViewController的preferredStatusBarStyle方法,這樣寫的話,就能保證當前顯示的UIViewController的preferredStatusBarStyle方法能被調用,從而實現statusBar的前景顏色。
然后在application didFinishLaunchingWithOptions:方法里把UINavigationController換成ZXNavigationController :
self.window.rootViewController = [[ZXNavigationController alloc] initWithRootViewController:viewVontroller];
Run一下,就會發現:齊活兒了~
如果設置了UIViewControllerBasedStatusBarAppearance為NO;那么就需要顯式地通過UIApplication對象來設置狀態欄的風格:
self.window.rootViewController = [[UINavigationController alloc] initWithRootViewController:viewVontroller];
//setStatusBarStyle從9.0開始不被推薦使用了:
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];
最后
說了這么多,簡單粗暴地概括下就是:如果想改變StatusBar的顯示風格,把UIViewControllerBasedStatusBarAppearance設置為NO,然后通過UIApplication對象設置StatusBar 的 Style。