天天看點

swift 隐藏狀态欄_詳解在iOS App中自定義和隐藏狀态欄的方法

自定義狀态欄

有時候,需要在狀态欄上顯示一些自定義資訊,比如新浪微網誌的官方iOS用戶端:告知使用者資訊處于發送隊列、發送成功或者發送失敗。

swift 隐藏狀态欄_詳解在iOS App中自定義和隐藏狀态欄的方法

如上圖,通過在狀态欄顯示自定義資訊,可以給使用者友好又不影響軟體使用的提示。

為此,我們顯得定義一個自定義狀态欄類,包含一個顯示資訊的Label:

@interface CustomStatusBar : UIWindow

{

UILabel *_messageLabel;

}

- (void)showStatusMessage:(NSString *)message;

- (void)hide;

@end

接着,設定大小和系統狀态欄一緻,背景為黑色:

self.frame = [UIApplication sharedApplication].statusBarFrame;

self.backgroundColor = [UIColor blackColor];

到這裡,為了讓自定義的狀态欄可以讓使用者看到,還需要設定它的windowLevel。

在iOS中,windowLevel屬性決定了UIWindow的顯示層次。預設的windowLevel為UIWindowLevelNormal,即0.0。

系統定義了三個層次如下,

const UIWindowLevel UIWindowLevelNormal;

const UIWindowLevel UIWindowLevelAlert;

const UIWindowLevel UIWindowLevelStatusBar;

typedef CGFloat UIWindowLevel;

為了能夠覆寫系統預設的狀态欄,我們把自定義的狀态欄的windowLevel調高點:

self.windowLevel = UIWindowLevelStatusBar + 1.0f;

隐藏狀态欄

如果想要隐藏狀态欄,有兩種做法:

狀态欄是否隐藏預設由控制器管理,也就是說,目前狀态欄所對應的控制器決定是否隐藏狀态欄。

UIViewController中提供了一個prefersStatusBarHidden方法用于檢視目前的控制器顯示的狀态欄是否隐藏,預設這個方法傳回的是NO,也就是不隐藏。但是并沒有提供相應的方法來設定隐藏狀态欄。

這種情況我們可以重寫prefersStatusBarHidden方法,通過修改它的傳回值達到目的。

- (BOOL)prefersStatusBarHidden

{

return YES;

}

這樣狀态欄就可以隐藏了。

另一種做法是不讓控制器來決定是否隐藏狀态欄,而是讓[UIApplication sharedApplication]來決定。

[UIApplication sharedApplication].statusBarHidden = YES;

運作程式發現狀态欄并沒有隐藏。檢視文檔可以發現:

Setting statusBarHidden does nothing if your application is using the default UIViewController-based status bar system.

意思是如果使用預設的控制器管理狀态欄(第一種做法提到的),那麼設定statusBarHidden是沒有效果的。想要關閉控制器的管理,需要我們給Info.plist增加一個key:

View controller-based status bar appearance

并且設定為NO,這樣就可以通過設定statusBarHidden來隐藏狀态欄了。(這個key是Info.plist添加Key出現的下拉欄裡的最後一個)

當控制器管理狀态欄時

- (UIViewController *)childViewControllerForStatusBarHidden

- (UIViewController *)childViewControllerForStatusBarStyle

這兩個方法可以将狀态欄的控制權交給子控制器管理,如果傳回nil則表示控制器自己來管理狀态欄;如果傳回子控制器,則表示子控制器來管理狀态欄。比如在navigation controller中實作prefersStatusBarHidden方法可能并不管用,因為它可能預設在childViewControllerForStatusBarHidden中傳回的是導航棧頂控制器,此時狀态欄由棧頂控制器來決定。如果想讓navigation controller來決定,那麼可以在類中按下面的方式實作:

- (UIViewController *)childViewControllerForStatusBarHidden

{

return nil;

}

此時,狀态欄的管理權在導航控制器。