正文
随便打开手机上的主流APP,我们不难发现它们的状态栏都是跟导航栏保持一致的背景颜色,如下图的微信和instagram:
那么今天我们就来说一下StatusBar这个只有区区20像素高度的小东西。
#UIStatusBarStyle
状态栏有两种显示风格:
1.UIStatusBarStyleDefault
2.UIStatusBarStyleLightContent
那么它的背景颜色是怎么加上去的呢?很简单,看代码:
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的前景颜色。