在项目中遇到有关状态栏样式的问题,于是查阅了相关资料,总结了一下。希望对其他简友们遇到相似的问题时有所帮助。有描述不对或者该补充的地方,也请各位多多指教。本文结构分两部分,第一部分为场景+设置方法;第二部分为相关的背景知识。
第一部分
场景一:
- 统一启动页和启动页之后的视图控制器状态栏内容样式为白色或黑色。
设置方式1:
进入Xcode
的Targets
->General
->DeploymentInfo
->Status Bar Style
,设置其值为Default
时,状态栏样式为黑色;设置其值为Light
时,状态栏样式为白色。
设置方式2:
在info.plist
文件中,找到Status bar style
键,设置其值为Gray style (default)
时,状态栏样式为黑色;设置其值为UIStatusBarStyleLightContent
时,状态栏样式为白色。
场景二:
- 整个应用程序状态栏样式统一为白色或黑色。
设置方式:
在
info.plist
文件中添加UIViewControllerBasedStatusBarAppearance
键,并设置其值为NO。-
在程序启动的地方设置,如下所示:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // Override point for customization after application launch. // 这种设置方式在iOS9之后废弃,采用 -[UIViewController preferredStatusBarStyle] [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent]; //统一状态栏样式为白色 //[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleDefault]; // 统一状态栏样式为黑色 return YES; }
场景三:
- 整个应用程序状态栏样式不统一。状态栏样式由各界面的视图控制器决定。
情况一:
- 该界面没有导航控制器
设置方式:
在
info.plist
文件中添加UIViewControllerBasedStatusBarAppearance
键,并设置其值为YES。或者删除UIViewControllerBasedStatusBarAppearance
键。-
在视图控制器中重写方法如下所示:
- (UIStatusBarStyle)preferredStatusBarStyle { return UIStatusBarStyleLightContent;// 该控制器下的状态栏样式为白色 // return UIStatusBarStyleDefault;// 该控制器下的状态栏样式为黑色 }
情况二:
- 该界面有导航控制器
设置方式:
在
info.plist
文件中添加UIViewControllerBasedStatusBarAppearance
键,并设置其值为YES。或者删除UIViewControllerBasedStatusBarAppearance
键。-
添加
UINavigationController
的分类(使用继承也可以),在分类中重写方法如下所示- (UIViewController *)childViewControllerForStatusBarStyle { return self.topViewController; // 返回导航控制器栈顶视图控制器,即当前显示的控制器。 }
-
在当前显示的视图控制器中,重写方法如下所示
- (UIStatusBarStyle)preferredStatusBarStyle { return UIStatusBarStyleLightContent;// 该控制器下的状态栏样式为白色 // return UIStatusBarStyleDefault;// 该控制器下的状态栏样式为黑色 }
第二部分
- 状态栏(
UIStatusBar
)的视图层级结构:
层级结构上分为背景视图部分和前景视图部分,前景视图部分包含无限网络连接标识,时间标识,蓝牙状态标识,电池电量标识等等可见内容。修改状态栏内容样式即改变前景视图内容的颜色,分为白色和黑色两种,白色样式主要用于界面背景为黑色的时候,黑色样式主要用于界面背景为浅色的时候。
- 关于前文中提到的
UIViewControllerBasedStatusBarAppearance
键:
官方文档关于此键的描述如下
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对象显示地设置状态栏样式。
当这个键设置为NO时,只能由UIApplication对象来控制状态栏样式。当设置为YES或不存在时,才能够使用控制器对象来控制状态栏样式。
- 关于前文中提到的
childViewControllerForStatusBarStyle
:
官方文档的描述如下:
Called when the system needs the view controller to use for determining status bar style.
If your container view controller derives its status bar style from one of its child view controllers, implement this method and return that child view controller. If you return nil or do not override this method, the status bar style for self is used. If the return value from this method changes, call the setNeedsStatusBarAppearanceUpdate method.
翻译:当系统需要视图控制器用于确定状态栏样式时调用。如果您的容器视图控制器从其子视图控制器中导出其状态栏样式,请执行此方法并返回该子视图控制器。 如果返回nil或不覆盖此方法,则会使用自身的状态栏样式。 如果此方法的返回值更改,请调用
setNeedsStatusBarAppearanceUpdate
方法。
当有导航控制器的时候,如果导航控制器的该方法返回nil,系统会调用导航控制器的preferredStatusBarStyle
方法取到返回值,来决定状态栏样式。在导航控制器的该方法中返回子视图控制器,则系统会调用其子视图控制器的preferredStatusBarStyle
方法来取到返回值,来决定状态栏样式。
- 关于上面提到的
setNeedsStatusBarAppearanceUpdate
:
官方文档的描述如下:
Indicates to the system that the view controller status bar attributes have changed.
Call this method if the view controller's status bar attributes, such as hidden/unhidden status or style, change. If you call this method within an animation block, the changes are animated along with the rest of the animation block.
翻译:向系统指示视图控制器状态栏属性已更改。如果视图控制器的状态栏属性(如隐藏/未隐藏状态或样式)发生更改,请调用此方法。 如果您在动画块中调用此方法,那么更改将与动画块的其余部分一起动画。
调用此方法会重写调用前面的childViewControllerForStatusBarStyle
和preferredStatusBarStyle
方法来重置一次状态栏。当想要主动改变状态栏样式时,可以主动调用此方法来重置状态栏样式。