专栏名称: Goyakod
iOS工程师
目录
相关文章推荐
雨果网  ·  4位亚马逊大卖拆解日本站的突围路径 ·  17 小时前  
中国电信  ·  女神,你的每一面都很美! ·  3 天前  
西安头条  ·  西安市属国企发布招聘公告 ·  3 天前  
中国电信  ·  全球首例!跨越5000公里的生命接力! ·  3 天前  
雨果网  ·  Manus整顿行业!大批运营随时面临失业 ·  3 天前  
51好读  ›  专栏  ›  Goyakod

iOS之StatusBar详解

Goyakod  · 掘金  ·  · 2017-12-17 08:56

正文

随便打开手机上的主流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.rootViewController preferredStatusBarStyle 方法,而不是当前控制器的 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.topViewController preferredStatusBarStyle 方法,这样写的话,就能保证当前显示的UIViewController的 preferredStatusBarStyle 方法能被调用,从而实现statusBar的前景颜色。







请到「今天看啥」查看全文