现在很多 APP 为了保持界面的统一,会让 iOS 状态栏的背景颜色和导航栏的颜色一致,有的时候还会隐藏状态栏,开发中修改状态栏往往一次弄好之后就不会再改变了,下面就记录一下各种调整状态栏颜色以及隐藏状态栏的设置(本文的内容只适用于 iOS7 及以上)
了解一下状态栏(UIStatusBar)
所谓状态栏就是我们的 iPhone 手机屏幕最顶端的20个像素高的那一部分,状态栏左边一般会有手机信号强度、运营商名字、Wi-Fi状态显示,中间会显示时间,状态栏右边会有定位显示、蓝牙显示已经电量显示
状态栏分两个部分:
- 前景部分:就是上面说到的时间、电量等
- 背景部分:就是状态栏背景
如图,上面的状态栏前景黑色,背景白色,下面的状态栏前景白色,背景黑色
设置 UIStatusBar 的前景部分
前景部分也就是时间、电量显示的这部分,有两种设置
- UIStatusBarStyleDefault(默认的黑色)
- UIStatusBarStyleLightContent(白色)
我们可以在 Info.plist
和代码里面设置这两种前景颜色样式
Info.plist
里面设置
在 Info.plist
里增加一个 Status bar style
的键,这个键对应的值就是我们需要的 UIStatusBarStyleDefault
或 UIStatusBarStyleLightContent
另外还需要在 Info.plist
增加一个 View controller-based status bar appearance
的键并且值设置为 NO
,这样 APP 启动之后前景的颜色样式就是 Info.plist
里面设置的风格了
代码里面设置
用 UIApplication
设置
|
|
这种方法也需要在 Info.plist
增加一个 View controller-based status bar appearance
的键并且值设置为 NO
这里解释一下 View controller-based status bar appearance
,这是官方文档的说明:
UIViewControllerBasedStatusBarAppearance (Boolean - iOS) Specifies whether the status bar appearance is based on the style preferred by the view controller that is currently under the status bar. When this key is not present or its value is set to YES, the view controller determines the status bar style. When the key is set to NO, view controllers (or the app) must each set the status bar style explicitly using the UIApplication object.
This key is supported in iOS 7.0 and later.
意思就是: 当该键不存在或其值设置为 YES
时,状态栏的样式由视图控制器决定(下面会讲到),当键设置为 NO
时,视图控制器(或应用程序)必须使用 UIApplication
对象显式地设置状态栏样式,这也解释了为什么上面的 Info.plist
和 UIApplication
设置状态栏样式需要把这个键设置为 NO
UIViewController
里设置
上面使用 UIApplication
设置状态栏的样式的方法在 iOS9 已经被废弃了,苹果推荐使用 UIViewController
的 - preferredStatusBarStyle
方法设置状态栏的样式,我们只需要在 UIViewController
里面重写 - preferredStatusBarStyle
方法,并返回需要的状态栏样式即可
|
|
这个方法需要注意:
- 控制器在显示的时候就会立即调用这个方法,并根据这个方法设置状态栏的样式
- 如果当前控制器已经显示出来了,你还希望可以改变当前的状态栏的样式,就需要用到另一个方法
- setNeedsStatusBarAppearanceUpdate
,这个方法会通知系统去调用当前UIViewController
的- preferredStatusBarStyle
方法,这样就可以重新设置当前控制器页面的状态栏样式了
但是实际使用中我们一般不会单独使用 ViewController
而是把 ViewController
加在 UINavigationController
里面使用,这个时候 ViewController
里面的 - preferredStatusBarStyle
方法并不会被调用,这个时候就需要用到 ViewController
的另一个方法 - childViewControllerForStatusBarStyle
如果是 ViewController
配合 UINavigationController
使用但是又希望状态栏的样式由当前的控制器决定,可以这样做:自定义一个继承自 UINavigationController
的子类,并且重写这个子类的 - childViewControllerForStatusBarStyle
方法:
|
|
重写这个方法的意思就是,不调用当前 UINavigationController
的- preferredStatusBarStyle
方法,而是去调用navigationController.topViewController
的preferredStatusBarStyle
方法,这样就能保证当前显示的UIViewController
的 preferredStatusBarStyle
可以决定状态栏的样式,除了重写子类的方法也可以使用分类的方法可以 参考这里
另外,有时我们当前显示的 UIViewController
可能添加了多个 childViewController
,重写当前 UIViewController
的childViewControllerForStatusBarStyle
方法,也可以使 childViewController
的 preferredStatusBarStyle
生效(当前 UIViewController
的 preferredStatusBarStyle
就不会被调用了)
总结起来就是:只要重写 UIViewController
的childViewControllerForStatusBarStyle
方法返回值不是nil
,那么这个 UIViewController
的 preferredStatusBarStyle
方法就不会被调用,而是会调用 childViewControllerForStatusBarStyle
这个方法返回的那个UIViewController
的 preferredStatusBarStyle
方法
设置 UIStatusBar 的背景部分
iOS7 以后默认情况下状态栏的背景为透明的,设置它的背景色有两种方法:
第一种是系统方法通过设置 navigationBar
的 barTintColor
颜色来改变状态栏颜色,另一种办法是我们自己写一个 UIView
作为背景添加到状态栏下面,这样就可以随意设置状态栏的颜色了
系统方法
|
|
如果你设置了 navigationBar
的 - setBackgroundImage:(UIImage *)backgroundImage forBarMetrics:(UIBarMetrics)barMetrics
,那么上面的 setBarTintColor
就就失效了
自定义 View
创建一个 UIView
,设置该 UIView
的 frame
和 statusBar
一样({0,-20,self.view.bounds.size.width,20}),然后设置该UIView
的背景色为你希望的状态栏的颜色,然后在 navigationBar
上addSubView
该 UIView
即可,这种方式,可以使状态的背景颜色和导航栏的背景颜色区不一样
状态栏隐藏
状态栏隐藏和设置的状态栏的前景样式方法是类似的,也分为两种情况,一种是在 Info.plist
里面设置,一种是在 `` 里面设置
Info.plist
设置隐藏状态栏
同样的也可以使用 UIApplication
的方法隐藏,但是记住 View controller-based status bar appearance
的要设置为 NO
|
|
有时候我们需要在 APP 启动页面隐藏状态栏,我们需要 Info.plist
里增加一个 Status bar is initially hidden
的键,设置为 YES
,这样就 APP 启动页面就会隐藏状态栏
以上的方法也是在 iOS9 之后被废弃了,苹果推荐使用 UIViewController
的 - prefersStatusBarHidden
方法
|
|
这个方法类似 preferredStatusBarStyle
,也有一个 childViewControllerForStatusBarHidden
的方法和 - childViewControllerForStatusBarStyle
对应,作用和上面修改状态栏前景样式是一样的,就不再赘述了,但是有点不一样
UIViewController
即使和UINavigationController
配合使用依然可以在自己的- prefersStatusBarHidden
方法里面返回YES
隐藏状态栏,只有当UIViewController
有多个childViewController
并且需要在某个childViewController
里面隐藏状态栏,这时候才需要重写UIViewController
的childViewControllerForStatusBarHidden
返回需要隐藏状态栏的那个childViewController
- 另外,调用
- setNeedsStatusBarAppearanceUpdate
方法也会刷新- prefersStatusBarHidden
方法
以上就是我关于 iOS 状态栏的设置的一些记录
本人刚开始写博客,主要是为了给自己的知识点做一个笔记,方便自己以后查阅,如果能让别人有所启发也是荣幸之至!如有错误,欢迎指正!