版本:
OS X 10.10.5
Xcode 6.4(6E35b)
iOS >= 7
一、概述
狀態欄(UIStatusBar)指iPhone/iPad/iPod屏幕頂部用於顯示網絡、時間和電量等的、高度為20點的控件。狀態欄的windowLevel為UIWindowLevelStatusBar,而window的windowLevel為UIWindowLevelNormal。所以一般情況下,狀態欄位於window之上。
二、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依賴於不同設備及橫豎屏。
三、UIStatusBarStyle(字體顏色)和背景顏色
UIStatusBarStyle控制狀態欄的字體顏色,在iOS7只支持兩種:UIStatusBarStyleDefault、UIStatusBarStyleLightContent。注意,雖然目前表現出來的顏色是黑色或白色,但不是Black或White之類的,蘋果留了一手以防以后改變。Default表示深色(Dark),用於亮色(Light)背景;LightContent表示亮色(Light),用於深色(Dark)背景。當然這也不是強制的。
在沒有導航欄的情況下,狀態欄的背景顏色是透明的,可以在View里添加一個20點高度的子View“偽造”一個背景;在有導航欄的情況下,狀態欄的背景顏色和狀態欄一樣,看起來融為了一體。
四、App啟動時狀態欄控制
App啟動的時候系統加載需要一定的時間,可以給App提供了Launch Image或Launch Screen以增強用戶體驗。在啟動頁顯示出來的時候App還沒有運行,也就談不上在程序中控制狀態欄的字體顏色、顯示或隱藏。
默認情況下狀態欄是顯示出來的,並且Style為UIStatusBarStyleDefault,即黑色。
1、隱藏
可以在Info中將Status bar is initially hidden(UIStatusBarHidden)對應的Value設置為Yes。
也可以在General中將Hide status bar勾選:
實際上,上面兩種設置方法最終作用到info.plist文件。可以直接修改該文件,如果不嫌麻煩又不擔心出錯的話。如果沒有使用基於ViewController的狀態欄控制,並且App內部又需要將狀態欄顯示出來,可以在AppDelegate中設置:[[UIApplication sharedApplication] setStatusBarHidden:NO];
2、設置字體顏色為白色
可以在Info中將Status bar style(UIStatusBarStyle)對應的Value設置為UIStatusBarStyeLightContent。
也可以在General中將Status Bar style選擇為Light:
同樣的,上面兩種設置方法最終作用到info.plist文件。如果沒有使用基於ViewController的狀態欄控制,並且App內部又需要將狀態欄顏色改為黑色,可以在AppDelegate中設置:
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleDefault];
五、App運行時狀態欄控制
新建一個Xcode項目,App默認是基於ViewController的狀態欄控制,即在ViewController重載prefersStatusBarHidden、preferredStatusBarStyle和preferredStatusBarUpdateAnimation三個方法,及在必要時調用setNeedsStatusBarAppearanceUpdate方法。
如果要使用iOS7之前的通過UIApplication控制狀態欄,需在target的info.plist中增加一條View controller-based status bar appearance(UIViewControllerBasedStatusBarAppearance)並設置為NO。
1、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];
}];
|
2、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。
六、示例代碼
可以根據是否是基於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
七、自定義狀態欄
見參考資料:
