iOS之StatusBar详解

作者: 啃手高手 | 来源:发表于2016-04-18 23:44 被阅读7730次

随便打开手机上的主流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地址

相关文章

  • iOS之StatusBar详解

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

  • React native StatusBar

    StatusBar详解 具体参数详解 StatusBar组件可以同时加载多个。此时属性会按照加载顺序合并(后者覆...

  • iOS Block实例

    iOS之Block详解:Block详解 ViewController.h(ARC) ViewController....

  • 2021-08-25

    iOS swift SDK详解之NSCoding协议 详解:NSCoding是对iOS中的Model类进行编码和解...

  • 单例

    iOS单例模式iOS之单例模式初探iOS单例详解

  • CGAffineTransform

    参考: iOS形变之CGAffineTransform iOS 仿射变换CGAffineTransform详解 如...

  • iOS开发之获取照片&&TZImagePicke

    iOS开发之获取照片&&TZImagePickerController的使用 iOS 开发之照片框架详解 objc...

  • uiscrollview

    IOS学习笔记——iOS组件之UIScrollView详解图解UIScrollView的contentOffset...

  • IOS学习(10)-UIImageView

    iOS开发笔记--UIImageView的属性之animationImages详解 IOS-UIImageView...

  • IOS学习(13)-UITextView

    UITextView详解iOS开发系列之四 – UITextView 用法小结UITextView控件的用法详解

网友评论

  • XTK_iOS:请问如何让StatusBar隐藏的时候Navigation高度不变?
  • 苦笑男神:博主您好,状态栏如何适配iOS9之前 和 iOS9之后呢,`info.plist`里面的值,要么NO,要么YES啊。NO的话,iOS9之后不建议使用,YES的话,iOS8会不会有问题?
  • StevenC:有用。顶一下!
    最好给出 Apple Doc 文档的相关链接,这样如果有要刨根问底的可以直接去看。
  • a24df6838a47:怎么在状态栏上添加事件呢
    a24df6838a47:@Goyakod 把手势加到哪里?
    啃手高手:@王晓鹏友 不确定会不会跟默认事件冲突,没试过,但是应该不会。
    啃手高手:@王晓鹏友 状态栏有默认事件会滚动到第一条,如果要加其他事件可以用手势也可以加按住。
  • 劉光軍_MVP:最后一句是重点
    啃手高手:@劉光軍_ 对,前面都是炫技。哈哈
  • _YZG_:我啥也没设置直接重写preferredStatusBarStyle方法, 可以实现啊..?我7.3
    啃手高手:@_YZG_ 没啥好处,就是知道其中的原理而已
    _YZG_:@Goyakod 那你这么做有什么好处呢
    啃手高手:@_YZG_ 是可以的。
  • 小如99:发现屏蔽 [self setNeedsStatusBarAppearanceUpdate];这行代码,电池栏的字体也能被修改成白色,为啥要调用这个呢?

    [[UIApplication sharedApplication] setStatusBarStyle 这个方法9.0不建议使用,9.0以后的版本可以在自定义的ZXNavigationController类中重写preferredStatusBarStyle方法:smile:
    小如99:@Goyakod 工程中的那个方法我已经屏蔽掉啦,是基于控制器的status,所以要屏蔽掉,然后又屏蔽掉setNeeds的这个方法,显示效果是一样的,你那边不是嘛?
    啃手高手:@小小如 文章介绍了这两种方法,如果两种都写了,哪个有效就取决于UIViewControllerBasedStatusBarAppearance这个bool值设置的是YES还是NO
    啃手高手:@小小如 “屏蔽 [self setNeedsStatusBarAppearanceUpdate];这行代码,电池栏的字体也能被修改成白色”是因为工程中有[[UIApplication sharedApplication] setStatusBarStyle方法
  • 来宝:可以设成一部分页面的StatusBar字体颜色为黑色,一部分页面为白色吗?这样一设置要么全黑,要么全白啊
    啃手高手:@来宝 设置成状态栏由视图控制器决定,然后每个就不同了,
  • 流刃若火泣:很实用!
  • 嫌疑人zx:感觉很有用

本文标题:iOS之StatusBar详解

本文链接:https://www.haomeiwen.com/subject/jdpalttx.html