zoukankan      html  css  js  c++  java
  • iOS之StatusBar详解

    随便打开手机上的主流APP,我们不难发现它们的状态栏都是跟导航栏保持一致的背景颜色,如下图的微信和instagram:


    WECHAT.PNG

    INS.PNG


    那么今天我们就来说一下StatusBar这个只有区区20像素高度的小东西。

    UIStatusBarStyle

    状态栏有两种显示风格:
    1.UIStatusBarStyleDefault


    default.png

    2.UIStatusBarStyleLightContent


    lightContent.png

    那么它的背景颜色是怎么加上去的呢?很简单,看代码:

    UIView *statusBar = [[UIView alloc] initWithFrame:CGRectMake(0, -20, self.view.frame.size.width, 20)];
    
    statusBar.backgroundColor = myColor;
    
    [self.navigationController.navigationBar addSubview:statusBar];

    看完代码就知道没什么可说的了。

    要改变状态栏的显示样式(前景颜色)需要在ViewContoller里重载方法:

    - (UIStatusBarStyle)preferredStatusBarStyle
    {
        return UIStatusBarStyleLightContent;
    }

    但是上面这个方法不能直接调用,需要通过下面这个方法来刷新状态栏的样式,例如:

    - (void)viewWillAppear:(BOOL)animated
    {
        [super viewWillAppear:animated];
    
        [self setNeedsStatusBarAppearanceUpdate];
    }

    如果你按照上面说的,在自己的ViewController里面设置一番之后,运行发现你的状态栏还是默认状态...那就对了,因为远没有那么容易。你还需要耐心往下看...

    UIViewControllerBasedStatusBarAppearance

    info.plist中可以设置状态栏的外观是否是基于视图控制器,键的名称就是UIViewControllerBasedStatusBarAppearance,如果不设置那么它的默认值是YES,表示视图控制器决定了状态栏的风格;如果值设置为NO,则表示每个视图控制器必须显式地使用UIApplication对象来设置状态栏的风格。

    哎~这个时候你肯定会疑惑了,我按照你上面说的没有设置plist文件啊,所以默认是YES,那么就是由视图控制器来决定状态栏风格啊,为什么不对呢?

    childViewControllerForStatusBarStyle

    当我们调用setNeedsStatusBarAppearanceUpdate时,系统会调用application.window.rootViewControllerpreferredStatusBarStyle方法,而不是当前控制器的preferredStatusBarStyle方法。在这个时候,一个重要的方法就要派上用场了,那就是:childViewControllerForStatusBarStyle

    childViewControllerForStatusBarStyle默认返回nil。所以我们需要重写这个方法。

    假设你的APP里根视图是导航控制器:

    self.window.rootViewController = [[UINavigationController alloc] initWithRootViewController:viewVontroller];

    那么,我们子类化一个导航控制器ZXNavigationController,重写它的childViewControllerForStatusBarStyle方法:

    @implementation ZXNavigationController
    
    - (UIViewController *)childViewControllerForStatusBarStyle
    {
        return self.topViewController;
    }
    
    - (void)viewDidLoad {
        [super viewDidLoad];
    }

    上面代码的意思就是说,不要调用我自己也就是UINavigationController的preferredStatusBarStyle方法,而是去调用navigationController.topViewControllerpreferredStatusBarStyle方法,这样写的话,就能保证当前显示的UIViewController的preferredStatusBarStyle方法能被调用,从而实现statusBar的前景颜色。

    然后在application didFinishLaunchingWithOptions:方法里把UINavigationController换成ZXNavigationController :

    self.window.rootViewController = [[ZXNavigationController alloc] initWithRootViewController:viewVontroller];

    Run一下,就会发现:齐活儿了~

    如果设置了UIViewControllerBasedStatusBarAppearanceNO;那么就需要显式地通过UIApplication对象来设置状态栏的风格:

    self.window.rootViewController = [[UINavigationController alloc] initWithRootViewController:viewVontroller];
    //setStatusBarStyle从9.0开始不被推荐使用了:
    [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];

    最后

    说了这么多,简单粗暴地概括下就是:如果想改变StatusBar的显示风格,把UIViewControllerBasedStatusBarAppearance设置为NO,然后通过UIApplication对象设置StatusBar 的 Style。

    Demo_Git地址

  • 相关阅读:
    PAT甲级1018Public Bike Management
    PAT甲级1003Emergency
    android的AIDL
    View的滑动冲突和解决方案
    弹性滑动原理
    View的滑动原理和多种滑动方法
    Android的Activity的生命周期
    Android获取App版本号和版本名
    转:Android检查设备是否联网
    androidstudio实现增量更新步骤
  • 原文地址:https://www.cnblogs.com/Free-Thinker/p/6478729.html
Copyright © 2011-2022 走看看