[iOS]關於狀態欄(UIStatusBar)的若干問題

版本:
OS X 10.10.5
Xcode 6.4(6E35b)
iOS >= 7

1、概述

狀態欄(UIStatusBar)指iPhone/iPad/iPod屏幕頂部用於顯示網絡、時間和電量等的、高度爲20點的控件。狀態欄的windowLevel爲UIWindowLevelStatusBar,而window的windowLevel爲UIWindowLevelNormal。因此通常狀況下,狀態欄位於window之上。

2、UIStatusBar的位置和尺寸

1 NSString *statusBarFrame = NSStringFromCGRect([UIApplication sharedApplication].statusBarFrame);
2 NSLog(@"%@", statusBarFrame);
 
在iPhone 6豎屏測試輸出:
2015-08-04 16:33:47.159 Test[6175:205261] {{0, 0}, {375, 20}}
在iPhone 6橫屏測試輸出:
2015-08-04 16:33:47.159 Test[6175:205261] {{0, 0}, {667, 20}}
在iPhone 6 Plus豎屏測試輸出:
2015-08-04 16:33:47.159 Test[6175:205261] {{0, 0}, {414, 20}}
 
可見其中origin.x和origin.y老是0,size.height老是20,size.width依賴於不一樣設備及橫豎屏。

3、UIStatusBarStyle(字體顏色)和背景顏色

UIStatusBarStyle控制狀態欄的字體顏色,在iOS7只支持兩種:UIStatusBarStyleDefault、UIStatusBarStyleLightContent。注意,雖然目前表現出來的顏色是黑色或白色,但不是Black或White之類的,蘋果留了一手以防之後改變。Default表示深色(Dark),用於亮色(Light)背景;LightContent表示亮色(Light),用於深色(Dark)背景。固然這也不是強制的。
在沒有導航欄的狀況下,狀態欄的背景顏色是透明的,能夠在View裏添加一個20點高度的子View「僞造」一個背景;在有導航欄的狀況下,狀態欄的背景顏色和狀態欄同樣,看起來融爲了一體。

4、App啓動時狀態欄控制

App啓動的時候系統加載須要必定的時間,能夠給App提供了Launch Image或Launch Screen以加強用戶體驗。在啓動頁顯示出來的時候App尚未運行,也就談不上在程序中控制狀態欄的字體顏色、顯示或隱藏。
默認狀況下狀態欄是顯示出來的,而且Style爲UIStatusBarStyleDefault,即黑色。

一、隱藏

能夠在Info中將Status bar is initially hidden(UIStatusBarHidden)對應的Value設置爲Yes。
也能夠在General中將Hide status bar勾選:
實際上,上面兩種設置方法最終做用到info.plist文件。能夠直接修改該文件,若是不嫌麻煩又不擔憂出錯的話。若是沒有使用基於ViewController的狀態欄控制,而且App內部又須要將狀態欄顯示出來,能夠在AppDelegate中設置:[[UIApplication sharedApplication] setStatusBarHidden:NO];

二、設置字體顏色爲白色

能夠在Info中將Status bar style(UIStatusBarStyle)對應的Value設置爲UIStatusBarStyeLightContent。
也能夠在General中將Status Bar style選擇爲Light:
一樣的,上面兩種設置方法最終做用到info.plist文件。若是沒有使用基於ViewController的狀態欄控制,而且App內部又須要將狀態欄顏色改成黑色,能夠在AppDelegate中設置:
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleDefault];

5、App運行時狀態欄控制

新建一個Xcode項目,App默認是基於ViewController的狀態欄控制,即在ViewController重載prefersStatusBarHidden、preferredStatusBarStyle和preferredStatusBarUpdateAnimation三個方法,及在必要時調用setNeedsStatusBarAppearanceUpdate方法。
若是要使用iOS7以前的經過UIApplication控制狀態欄,需在target的info.plist中增長一條View controller-based status bar appearance(UIViewControllerBasedStatusBarAppearance)並設置爲NO。
 

一、View controller-based status bar appearance : YES 或 info.plist無此條目

 
UIViewController方法 說明
- (BOOL)prefersStatusBarHidden NS_AVAILABLE_IOS(7_0); // Defaults to NO 詢問是否隱藏狀態欄。
- (UIStatusBarStyle)preferredStatusBarStyle NS_AVAILABLE_IOS(7_0); // Defaults to UIStatusBarStyleDefault 詢問狀態欄樣式(UIStatusBarStyleDefault/UIStatusBarStyleLightContent)。
// Override to return the type of animation that should be used for status bar changes for this view controller. This currently only affects changes to prefersStatusBarHidden.
- (UIStatusBarAnimation)preferredStatusBarUpdateAnimation NS_AVAILABLE_IOS(7_0); // Defaults to UIStatusBarAnimationFade
詢問狀態欄顯示或隱藏動畫。
// This should be called whenever the return values for the view controller's status bar attributes have changed. If it is called from within an animation block, the changes will be animated along with the rest of the animation block.
- (void)setNeedsStatusBarAppearanceUpdate NS_AVAILABLE_IOS(7_0);
設置須要更新狀態欄。主動調用該方法,將間接調用上述三個方法。若是須要動畫生效,需:
    [UIView animateWithDuration:0.4
                     animations:^{
                         [self setNeedsStatusBarAppearanceUpdate];
                     }];
   
 

二、View controller-based status bar appearance : NO 

 
UIApplication方法/屬性 說明
// Setting statusBarHidden does nothing if your application is using the default UIViewController-based status bar system.
@property(nonatomic,getter=isStatusBarHidden) BOOL statusBarHidden;
- (void)setStatusBarHidden:(BOOL)hidden withAnimation:(UIStatusBarAnimation)animation NS_AVAILABLE_IOS(3_2);
設置是否隱藏狀態欄。
// Setting statusBarHidden does nothing if your application is using the default UIViewController-based status bar system.
@property(nonatomic) UIStatusBarStyle statusBarStyle; // default is UIStatusBarStyleDefault
- (void)setStatusBarStyle:(UIStatusBarStyle)statusBarStyle animated:(BOOL)animated;
設置狀態欄樣式(UIStatusBarStyleDefault/UIStatusBarStyleLightContent)。
   
 
若是要在App啓動時和運行時全程隱藏狀態欄,在View controller-based status bar appearance爲NO的狀況下,只需簡單將Status bar is initially hidden(UIStatusBarHidden)設置爲YES。

6、示例代碼

能夠根據是不是基於ViewController的狀態欄控制來決定是否調用UIApplication中控制狀態欄的相關方法,也能夠直接調用。由於在基於ViewController的狀態欄控制時,調用UIApplication中控制狀態欄的相關設置方法會被忽略。
@interface ViewController ()

@property (nonatomic) BOOL statusBarIsHidden;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    self.statusBarIsHidden = NO;
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];

    [UIApplication sharedApplication].statusBarStyle = UIStatusBarStyleDefault;

    [self performSelector:@selector(setStatusBarHidden:) withObject:@(YES) afterDelay:3.];
    [self performSelector:@selector(setStatusBarHidden:) withObject:@(NO) afterDelay:6.];
}

- (void)setStatusBarHidden:(BOOL)hidden
{
    self.statusBarIsHidden = hidden;
    [UIView animateWithDuration:0.4
                     animations:^{
                         [self setNeedsStatusBarAppearanceUpdate];
                     }];
    [[UIApplication sharedApplication] setStatusBarHidden:hidden withAnimation:UIStatusBarAnimationSlide];
}

- (UIStatusBarStyle)preferredStatusBarStyle
{
    return UIStatusBarStyleDefault;
}

- (BOOL)prefersStatusBarHidden
{
    return self.statusBarIsHidden;
}

- (UIStatusBarAnimation)preferredStatusBarUpdateAnimation
{
    return UIStatusBarAnimationSlide;
}

@end
7、自定義狀態欄
見參考資料:
相關文章
相關標籤/搜索