iOS之StatusBar詳解

隨便打開手機上的主流APP,我們不難發現它們的狀態欄都是跟導航欄保持一致的背景顏色,如下圖的微信和instagram:


WECHAT.PNG

INS.PNG

那么今天我們就來說一下StatusBar這個只有區區20像素高度的小東西。

UIStatusBarStyle

狀態欄有兩種顯示風格:
1.UIStatusBarStyleDefault

default.png

2.UIStatusBarStyleLightContent

lightContent.png

那么它的背景顏色是怎么加上去的呢?很簡單,看代碼:

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.rootViewControllerpreferredStatusBarStyle方法,而不是當前控制器的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.topViewControllerpreferredStatusBarStyle方法,這樣寫的話,就能保證當前顯示的UIViewController的preferredStatusBarStyle方法能被調用,從而實現statusBar的前景顏色。

然后在application didFinishLaunchingWithOptions:方法里把UINavigationController換成ZXNavigationController :

self.window.rootViewController = [[ZXNavigationController alloc] initWithRootViewController:viewVontroller];

Run一下,就會發現:齊活兒了~

如果設置了UIViewControllerBasedStatusBarAppearanceNO;那么就需要顯式地通過UIApplication對象來設置狀態欄的風格:

self.window.rootViewController = [[UINavigationController alloc] initWithRootViewController:viewVontroller];
//setStatusBarStyle從9.0開始不被推薦使用了:
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];

最后

說了這么多,簡單粗暴地概括下就是:如果想改變StatusBar的顯示風格,把UIViewControllerBasedStatusBarAppearance設置為NO,然后通過UIApplication對象設置StatusBar 的 Style。

Demo_Git地址

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容