關(guān)于iOS狀態(tài)欄處理的相關(guān)方法變更:
1、iOS9以前是statusBarStyle相關(guān)樣式都是由UIApplication全局統(tǒng)一配置,iOS9之后這些方法便遺棄了(使用的話需要plist設(shè)置View controller-based status bar appearance為NO)。
- (void)setStatusBarHidden:(BOOL)hidden animated:(BOOL)animated;
- (void)setStatusBarStyle:(UIStatusBarStyle)statusBarStyle animated:(BOOL)animated;
- (void)setStatusBarHidden:(BOOL)hidden withAnimation:(UIStatusBarAnimation)animation;
@property(readwrite, nonatomic,getter=isStatusBarHidden) BOOL statusBarHidden;
2、iOS7將其添加為UIViewController的屬性(需要plist設(shè)置View controller-based status bar appearance為YES):
@property(nonatomic, readonly, nullable) UIViewController *childViewControllerForStatusBarStyle;
@property(nonatomic, readonly, nullable) UIViewController *childViewControllerForStatusBarHidden;
@property(nonatomic, readonly) UIStatusBarStyle preferredStatusBarStyle;
@property(nonatomic, readonly) BOOL prefersStatusBarHidden;
@property(nonatomic, readonly) UIStatusBarAnimation preferredStatusBarUpdateAnimation;
- (void)setNeedsStatusBarAppearanceUpdate;
新方法說明:
? ?新的api提供了自父控制器到子控制器的逐層控制,即由誰來控制狀態(tài)欄是上層控制器用childViewControllerForStatusBarHidden和childViewControllerForStatusBarStyle方法來決定的。如果這兩個方法在控制器中都返回nil,則由自己控制。
1.childViewControllerForStatusBarStyle和childViewControllerForStatusBarHidden,在UITabBarController、UINavigationController、UIViewController中實現(xiàn),返回一個子控制器來控制狀態(tài)欄的hidden和樣式。
UINavigationController:
? ?childViewControllerForStatusBarHidden默認(rèn)返回值是topViewController
? ?childViewControllerForStatusBarStyle默認(rèn)返回值是nil? ? ??
? ?當(dāng)childViewControllerForStatusBarStyle返回nil,如果父控制器指定了childViewControllerForStatusBarStyle為UINavigationController,則preferredStatusBarStyle會被調(diào)用
UITabBarController:
? ?childViewControllerForStatusBarStyle和childViewControllerForStatusBarHidden默認(rèn)都是selectedViewController,所以在UITabBarController里面實現(xiàn)prefersStatusBarHidden和preferredStatusBarStyle默認(rèn)是不會調(diào)用的。
? ?以前A控制器push到B控制器,B控制器pop到A,而且A、B兩個控制器需要的狀態(tài)欄樣式不同。那么就需要在A、B中調(diào)用:
A:[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent]
B:[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleDefault]
? ?那么現(xiàn)在我們只需要在controller中實現(xiàn)如下方法,該方法就會每次在viewWillAppear之前調(diào)用:
- (UIStatusBarStyle)preferredStatusBarStyle { ?
?????if (@available(iOS 13.0, *)) {? ? ? ?
????????return UIStatusBarStyleLightContent;? ?
????} else {? ? ? ?
????????return UIStatusBarStyleDefault;? ? ? ?
? }}
各方法調(diào)用順序:
1.當(dāng)做視圖切換操作時,首先會自上而下調(diào)用:
- UITabBarController ????????-?childViewControllerForStatusBarHidden
- UINavigationController -?childViewControllerForStatusBarHidden
- currentUIViewController(即將disappear) ? ? ? ? ? ? -?prefersStatusBarHidden
- UITabBarController ????????-childViewControllerForStatusBarHidden
- UINavigationController -?childViewControllerForStatusBarHidden
- nextUIViewController (即將appear)? ?????????????????-?prefersStatusBarHidden
- nextUIViewController (即將appear)? ? ? -??preferredStatusBarUpdateAnimation(statusBarHidden有變化會執(zhí)行)
2.這時如果nextUIViewController的prefersStatusBarHidden返回YES,則直接隱藏。如果為NO,繼續(xù)自上而下調(diào)用:
- UITabBarController ????????-childViewControllerForStatusBarStyle
- UINavigationController -?childViewControllerForStatusBarStyle
- UIViewController (即將appear) ? ? ? ? ? ? ?-preferredStatusBarStyle
對于modal出來的控制器,如果modalPresentationStyle是fullScreen,那么就可以由modal出來的控制器處理。如果不是fullScreen就可以實現(xiàn)modalPresentationCapturesStatusBarAppearance返回YES來處理,否則就會交給下面的ViewController來處理。
除此之外新版的statusBar顯隱的動畫將不能直接設(shè)置,雖然有preferredStatusBarUpdateAnimation這個方法可以返回動畫樣式,但并沒有動畫效果。需要我們在改變hidden的時候由控制器手動添加動畫并調(diào)用setNeedsStatusBarAppearanceUpdate刷新:
? ? [UIView animateWithDuration:0.5 animations:^{
? ? ? ? [self setNeedsStatusBarAppearanceUpdate];? ?
}];
如果需要在控制器內(nèi)(而不是切換控制器)主動改變狀態(tài)欄,就需要在改變后(一般設(shè)立flag,通過修改flag,控制prefer方法的返回值)調(diào)用setNeedsStatusBarAppearanceUpdate來刷新樣式,系統(tǒng)會再次自上而下調(diào)用以上相關(guān)方法。