设置UIstatusBarStyle的正确姿势

设置UIstatusBarStyle的正确姿势 

发表于 2019-10-11 | 分类于 测试 | 没有评论

一. 前言

iOS开发过程中经常会修改导航栏的背景色(或者设置透明渐变),为了适配背景色,需要对状态栏的颜色进行变更,本文主要介绍对状态栏颜色的变更。

二. 正文

状态栏颜色变更可以理解为其样式的变更,通过苹果API可知状态栏有以下几种样式: 

后两种已经弃用,主要是下面两种: 

UIStatusBarStyleDefault:默认的黑色字体内容,主要用与浅色背景。

UIStatusBarStyleLightContent:默认的浅色内容(白色),主要用于深色背景。 

设置APP启动时状态栏状态

在info.plist文件中,开发者可以设置UIStatusBarStyle和UIStatusBarHidden选项,该选项说明如下:

默认情况下: 


UIStatusBarStyle值为:UIStatusBarStyleDefault

UIStatubBarHidden值为:NO

开发者可以在Info.plist中进行设置两个值来控制在启动页展示的时候状态栏是否隐藏以及其Style。接下来需要关注另外一个key:UIViewControllerBasedStatusBarAppearance。该key的作用是指示状态栏的外观是否基于当前控制器的样式。该值默认为YES,如果设置为NO,则在Info.plist中设置的UIStatusBarStyle和UIStatubBarHidden就会状态保持。也就是说如果为NO,并且设置UIStatubBarHidden为NO,那APP启动之后是不展示状态栏的。如果UIViewControllerBasedStatusBarAppearance设置为YES或者不设置(默认为YES),在Info.plist中设置只会影响APP启动时状态栏的样式,不会影响启动之后进入首页的样式。

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.状态栏UIStatusBarStyle设置

设置状态栏样式

在程序进入前台之后,开发者可以通过下面两种方式更改状态栏的状态:

第一种方式:通过setStatusBarStyle设置

直接使用UIApplication提供的方法进行设置: 

运行之后发现状态栏内容颜色依然为黑色,为什么没有生效呢?原来是需要在info.plist中设置UIViewControllerBasedStatusBarAppearance为NO。设置为NO之后,该方式才能设置成功。该方式有两个问题: 

该设置方式在iOS9之后就被弃用了,苹果建议使用preferredStatusBarStyle进行设置。当然如果你的APP想要支持iOS9之前的版本,则需要对版本进行判断。 

如果只想为某个页面设置UIStatusBarStyleLightContent,入口页面保持不变,则需要对状态进行还原。即在特定VC中的viewWillAppear中设置为UIStatusBarStyleLightContent,在viewWillDisappear中设置为UIStatusBarStyleDefault。否则将会影响其他页面状态栏样式展示。 

第二种方式:通过重写preferredStatusBarStyle设置

通过这种方式设置状态时,需要将UIViewControllerBasedStatusBarAppearance设置为YES(或者不设置,默认为YES)。然后在VC中重写preferredStatusBarStyle: 

运行程序发现不生效。看下该方法的说明: 

You can override the preferred status bar style for a view controller by implementing the childViewControllerForStatusBarStyle method.

If the return value from this method changes, call the setNeedsStatusBarAppearanceUpdate method.

看说明是需要实现childViewControllerForStatusBarStyle方法。看到childViewController,一般会联想到navigationController和tabBarController,他们都有自己的childViewController。因为测试的Demo是有navigation导航的,有没有可能是因为需要重写一下navigationController的看说明是需要实现childViewControllerForStatusBarStyle方法呢?因此做了如下尝试:将ViewController直接设置为window的rootVC,再次运行,发现生效了。因此可能是由navigationController导致的问题。

接下来实现NavigationController的子类,然后在子类中实现如下方法: 

然后再次运行程序,发现这次在ViewController中设置的样式生效了。经过测试发现:如果在navigationController中不实现childViewControllerForStatusBarStyle,则会调用navigationController的preferredStatusBarStyle。如果实现了该方法,该方法会返回导航栈最顶层的VC。 

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 setNeedsStatusBarAppearanceUpdatemethod.

从childViewControllerForStatusBarStyle文档可知,如果开发者想要通过navigationController的子VC来重写导航栈,那就需要通过该方法将特定的VC返回。这里总是返回最顶层的VC。

因此如果发现带导航栈APP的preferredStatusBarStyle不生效,可以对childViewControllerForStatusBarStyle进行重写。

状态栏的隐藏方法prefersStatusBarHidden和preferredStatusBarStyle类似,也是需要实现childViewControllerForStatusBarHidden。这里就不再赘述。

这里需要注意的是:当在VC中对状态栏的状态进行重设(prefersStatusBarHidden 或者preferredStatusBarStyle返回值有所变更)每次对状态栏状态进行变更,都需要调用setNeedsStatusBarAppearanceUpdate方法,该方法会告诉系统,VC的状态栏状态发生改变,进而会重新调用prefersStatusBarHidden或者preferredStatusBarStyle。 

注意点

每次状态栏状态之后,需要调用一下setNeedsStatusBarAppearanceUpdate方法。

如果是UITabBarController,也需要实现childViewControllerForStatusBarStyle(或者childViewControllerForStatusBarHidden)来指定特定VC(TabBarController中重写childViewControllerForStatusBar 返回tabBarController的selectedViewController )。

原文来自:https://www.dazhuanlan.com/2019/10/11/5d9fec7aeed1b/

参考

UIViewControllerBasedStatusBarAppearance

Information Property List Key Reference

https://stackoverflow.com/questions/45372550/preferredstatusbarstyle-is-not-working

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,294评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,493评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,790评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,595评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,718评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,906评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,053评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,797评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,250评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,570评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,711评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,388评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,018评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,796评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,023评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,461评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,595评论 2 350