先說下iOS9之前的方法
——————iOS9之前——————
全局隱藏狀態(tài)欄和設(shè)置樣式
1、在工程的info.plist文件中, 添加View controller-based status bar appearance-->值為: NO
2、在AppDelegate中加上[[UIApplication sharedApplication] setStatusBarHidden:YES];
3.設(shè)置狀態(tài)欄樣式[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent/UIStatusBarStyleDefault];
@interface UIApplication(UIApplicationDeprecated)
// Setting statusBarHidden does nothing if your application is using the default UIViewController-based status bar system.
@property(readwrite, nonatomic,getter=isStatusBarHidden) BOOL statusBarHidden
NS_DEPRECATED_IOS(2_0, 9_0, "Use -[UIViewController prefersStatusBarHidden]") __TVOS_PROHIBITED;
- (void)setStatusBarHidden:(BOOL)hidden withAnimation:(UIStatusBarAnimation)animation
NS_DEPRECATED_IOS(3_2, 9_0, "Use -[UIViewController prefersStatusBarHidden]") __TVOS_PROHIBITED;
// Setting statusBarHidden does nothing if your application is using the default UIViewController-based status bar system.這句注釋表明,如果使用視圖控制器去設(shè)置狀態(tài)欄,UIApplication里的statusBarHidden方法不生效,setStatusBarStyle同理。所以要View controller-based status bar appearance-->值為:NO
某些頁面隱藏狀態(tài)欄和設(shè)置樣式
由于[UIApplication sharedApplication]是全局性的,只要設(shè)置過一次隱藏,所有頁面都是會(huì)隱藏狀態(tài)欄。如果你想要在某些頁面單獨(dú)設(shè)置隱藏狀態(tài)欄,先在AppDelegate中設(shè)置顯示狀態(tài)欄[[UIApplication sharedApplication] setStatusBarHidden:NO];然后在某一個(gè)ViewController的viewWillAppear里設(shè)置隱藏,再在viewWillDisappear里還原之前的設(shè)置。
狀態(tài)欄樣式同理。
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[[UIApplication sharedApplication] setStatusBarHidden:YES];
}
- (void)viewWillDisappear:(BOOL)animated{
[super viewWillDisappear:animated];
[[UIApplication sharedApplication] setStatusBarHidden:NO];
}
——————iOS9之后————————
iOS9之后上述的方法蘋果已經(jīng)不推薦使用了,這些方法能用但是會(huì)報(bào)警告。注釋提示蘋果推薦使用Use -[UIViewController prefersStatusBarHidden] 這是iOS7之后蘋果在UIViewController里添加的新方法,這么做的目的可以讓開發(fā)者更加靈活的自定義每個(gè)ViewController的狀態(tài)欄。
如果要使用prefersStatusBarHidden方法,那么必須將View controller-based status bar appearance-->值為: YES,并且setStatusBarHidden和setStatusBarStyle方法會(huì)失效
取而代之的是:
- (BOOL)preferredStatusBarHidden{
return YES;
}
- (UIStatusBarStyle)preferredStatusBarStyle{
return UIStatusBarStyleLightContent;
}
只要在UIViewController里重寫了這兩個(gè)方法,那么在ViewController顯示的時(shí)候狀態(tài)欄就會(huì)變成上面設(shè)置的樣式
全局隱藏狀態(tài)欄和設(shè)置樣式
改用[UIViewController prefersStatusBarHidden]方法設(shè)置狀態(tài)欄之后,APP運(yùn)行后,應(yīng)用不再讀取UIApplication 的statusBarHidden和statusBarStyle這兩個(gè)屬性去設(shè)置狀態(tài)欄,而是根據(jù)AppDelegate.window.rootViewController里的方法,這時(shí)首先會(huì)調(diào)用的是rootViewController中的childViewControllerForStatusBarHidden函數(shù),因?yàn)槟J(rèn)返回nil,那么接下來就會(huì)調(diào)用rootViewController本身的prefersStatusBarHidden方法和preferredStatusBarStyle方法。因此想要全局設(shè)置狀態(tài)欄,只要在根視圖rootViewController里重寫這倆個(gè)方法即可。
但是通常來說AppDelegate.window.rootViewController都是UINavigationController,應(yīng)用只會(huì)調(diào)用UINavigationController的方法,返回都是默認(rèn)值,所以已經(jīng)在自己的ViewController里寫了- preferredStatusBarHidden, 卻一點(diǎn)都不起作用。
當(dāng)AppDelegate.window.rootViewController是UINavigationController,想要全局設(shè)置狀態(tài)欄和樣式,可以在UINavigationController里重寫prefersStatusBarHidden方法和preferredStatusBarStyle方法即可
某些頁面隱藏狀態(tài)欄和設(shè)置樣式
當(dāng)AppDelegate.window.rootViewController是UINavigationController,不能在UINavigationController里重寫prefersStatusBarHidden方法和preferredStatusBarStyle方法,而是自己創(chuàng)建一個(gè)繼承于UINavigationcontroller的NavigationController,在這個(gè)子類中重寫childViewControllerForStatusBarHidden 和childViewControllerForStatusBarStyle函數(shù)
- (UIViewController *)childViewControllerForStatusBarHidden{
return self.topViewController;
}
- (UIViewController *)childViewControllerForStatusBarStyle{
return self.topViewController;
}
然后在每一個(gè)新的ViewController里根據(jù)需要重寫prefersStatusBarHidden方法和preferredStatusBarStyle方法
這樣每push或者pop一個(gè)vc,狀態(tài)欄都是根據(jù)最上層的vcprefersStatusBarHidden方法和preferredStatusBarStyle方法去設(shè)置
setNeedsStatusBarAppearanceUpdate
UIViewController里的prefersStatusBarHidden方法和preferredStatusBarStyle方法,系統(tǒng)調(diào)用時(shí)機(jī)早于ViewController顯示時(shí)viewDidAppear,因此只能決定ViewController顯示時(shí)的狀態(tài)欄,如果之后狀態(tài)欄發(fā)生變化,需要顯示的調(diào)用setNeedsStatusBarAppearanceUpdate
@property (nonatomic, assign) BOOL statusBarHidden;
- (BOOL)preferredStatusBarHidden{
return self.statusBarHidden;
}
- (void)needChangeStatusBarHidden {
self.statusBarHidden = YES;
[self setNeedsStatusBarAppearanceUpdate]; //立即更新狀態(tài)欄
}