iOS9状态栏处理方法变更

关于iOS状态栏处理的相关方法变更:

1、iOS9以前是statusBarStyle相关样式都是由UIApplication全局统一配置,iOS9之后这些方法便遗弃了(使用的话需要plist设置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设置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提供了自父控制器到子控制器的逐层控制,即由谁来控制状态栏是上层控制器用childViewControllerForStatusBarHidden和childViewControllerForStatusBarStyle方法来决定的。如果这两个方法在控制器中都返回nil,则由自己控制。

1.childViewControllerForStatusBarStyle和childViewControllerForStatusBarHidden,在UITabBarController、UINavigationController、UIViewController中实现,返回一个子控制器来控制状态栏的hidden和样式。

UINavigationController

   childViewControllerForStatusBarHidden默认返回值是topViewController

   childViewControllerForStatusBarStyle默认返回值是nil      

   当childViewControllerForStatusBarStyle返回nil,如果父控制器指定了childViewControllerForStatusBarStyle为UINavigationController,则preferredStatusBarStyle会被调用

UITabBarController:

   childViewControllerForStatusBarStyle和childViewControllerForStatusBarHidden默认都是selectedViewController,所以在UITabBarController里面实现prefersStatusBarHidden和preferredStatusBarStyle默认是不会调用的。

   以前A控制器push到B控制器,B控制器pop到A,而且A、B两个控制器需要的状态栏样式不同。那么就需要在A、B中调用:

A:[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent]

B:[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleDefault]

   那么现在我们只需要在controller中实现如下方法,该方法就会每次在viewWillAppear之前调用:

- (UIStatusBarStyle)preferredStatusBarStyle {  

     if (@available(iOS 13.0, *)) {       

        return UIStatusBarStyleLightContent;   

    } else {       

        return UIStatusBarStyleDefault;       

  }}


各方法调用顺序:

1.当做视图切换操作时,首先会自上而下调用:

- UITabBarController         - childViewControllerForStatusBarHidden

- UINavigationController - childViewControllerForStatusBarHidden

- currentUIViewController(即将disappear)             - prefersStatusBarHidden

- UITabBarController         -childViewControllerForStatusBarHidden

- UINavigationController - childViewControllerForStatusBarHidden

- nextUIViewController (即将appear)                   - prefersStatusBarHidden

- nextUIViewController (即将appear)      -  preferredStatusBarUpdateAnimation(statusBarHidden有变化会执行)

2.这时如果nextUIViewController的prefersStatusBarHidden返回YES,则直接隐藏。如果为NO,继续自上而下调用:

- UITabBarController         -childViewControllerForStatusBarStyle

- UINavigationController - childViewControllerForStatusBarStyle

- UIViewController (即将appear)              -preferredStatusBarStyle

对于modal出来的控制器,如果modalPresentationStylefullScreen,那么就可以由modal出来的控制器处理。如果不是fullScreen就可以实现modalPresentationCapturesStatusBarAppearance返回YES来处理,否则就会交给下面的ViewController来处理。

除此之外新版的statusBar显隐的动画将不能直接设置,虽然有preferredStatusBarUpdateAnimation这个方法可以返回动画样式,但并没有动画效果。需要我们在改变hidden的时候由控制器手动添加动画并调用setNeedsStatusBarAppearanceUpdate刷新:

    [UIView animateWithDuration:0.5 animations:^{

        [self setNeedsStatusBarAppearanceUpdate];   

}];

如果需要在控制器内(而不是切换控制器)主动改变状态栏,就需要在改变后(一般设立flag,通过修改flag,控制prefer方法的返回值)调用setNeedsStatusBarAppearanceUpdate来刷新样式,系统会再次自上而下调用以上相关方法。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。