iOS 13 状态栏样式无效(childForStatusBarStyle 从未调用)

Posted

技术标签:

【中文标题】iOS 13 状态栏样式无效(childForStatusBarStyle 从未调用)【英文标题】:iOS 13 Status bar style invalid (childForStatusBarStyle never called) 【发布时间】:2020-12-02 06:38:06 【问题描述】:

我搜索了很多,但在 *** 或其他任何地方都没有找到与我相同的问题。


设置

Info.plist ViewControllerBasedStatusBar 设置为 YES StatusBarStyle 设置为 .lightContent UserInterfaceStyle 设置为.light(应用不支持.dark 模式) 每个UIViewController 都有自己的preferredStatusBarStyle 实现:
override var preferredStatusBarStyle: UIStatusBarStyle 
    return .lightContent

UITabBarControllerextension:
open override var childForStatusBarStyle: UIViewController? 
    return selectedViewController

UINavigationControllerextension:
override open var childForStatusBarStyle: UIViewController? 
    return topViewController


问题

自从 ios 13 发布以来,我的状态栏逻辑被破坏了,我不明白为什么。在 iOS childForStatusBarStyle 永远不会被调用,并且每个 viewController 都有一些随机样式

更新:由于 iOS 13 发布状态的样式基于 UserInterfaceStyle 设置全局,而不是基于 preferredStatusBarStyle(正确设置)UITabBarController -> UINavigationController - > UIViewController 层次结构。


问题

问题是如何解决这个问题?这个逻辑有什么悄悄改变吗? (检查了许多文章和更新日志)


复制

按照上述设置,我已经能够在示例项目中重现该错误。

Here我有一个包含如下视图层次结构的github项目:

CustomTabBarController
 - UINavigationController
   - CustomViewController
 - CustomViewController

现在,当你选择第一个标签应用程序有深色风格的状态栏时,当第二个选择浅色风格时。 CustomViewController 将preferredStatusBarStyle 设置为.lightContent

更多

Xcode:版本 11.5 (11E608c) 设备:iPhone 8 模拟器 iOS:版本 13.5

P.S:我已准备好并会提供有关该主题的更多详细信息,请随时要求我这样做。项目运行了 2 年多,这样的事情真的要调试了 :)

【问题讨论】:

请发minimal reproducible example 并发布。 @matt 好的,我会尝试创建示例项目 谢谢,这将是一个很大的帮助。 是的,看起来像一个错误,让我们向 Apple 提交反馈。 @matt 我刚刚添加了带有描述问题的示例项目。可以看看吗? 【参考方案1】:

对于那些在时间紧迫的情况下使用.barStyle 很重要的人,有一种解决方法。子类UINavigationController,然后每次viewControllers更改时调用setNeedsStatusBarAppearanceUpdate


示例代码

class WorkaroundNavigationController: UINavigationController 
    override var childForStatusBarStyle: UIViewController? 
        return topViewController
    
    
    override var viewControllers: [UIViewController] 
        didSet  setNeedsStatusBarAppearanceUpdate() 
    

【讨论】:

非常感谢【参考方案2】:

在导航控制器的情况下,状态栏样式(亮/暗)不依赖,也从来没有依赖于导航栏样式以外的任何东西。在项目的自定义标签栏中添加这一行:

    let bugVC = UINavigationController(rootViewController: ViewController())
    bugVC.navigationBar.barStyle = .black // *

现在标签栏控制器的两个子标签栏的状态栏文本都是白色的。 (如果您不喜欢导航栏的颜色,默认为黑色,您可以更改它;这不会影响状态栏的行为。)

【讨论】:

如果您查看我为这两种方法实现的扩展(UITabBarControllerUINavigationControllerchildForStatusBarStyle 并且在第一个选项卡中必须有 preferredStatusBarStyleViewController 不需要敌对。如果您查看我的答案,它会告诉您如何在导航控制器的情况下使状态栏变亮。我坚持这一点。我告诉你的总是正确的方法。例如,在这里查看我的答案:***.com/questions/47837959/… 感谢您的回答!没有什么敌对的,非常感谢您的帮助!我去看看。 我刚刚将示例项目降级为iOS 12.4 部署目标,它按预期工作(一直在工作)。请尝试在12.4 模拟器上运行它。调用childForStatusBarStyle 中的打印并将UINavigationController 的状态栏样式设置为ViewController 类的preferredStatusBarStyle 中返回的内容。 然后,尝试在13+ iOS 上再次运行,并且不会调用 print。所以这就是我问的问题:“问题是如何解决这个问题?这个逻辑有没有悄悄改变?(检查了很多文章和更新日志)”

以上是关于iOS 13 状态栏样式无效(childForStatusBarStyle 从未调用)的主要内容,如果未能解决你的问题,请参考以下文章

iOS 15 中的状态栏样式不变

ios设置状态栏样式

iOS 13后状态栏获取高度的方法

如何在 iOS 7 启动期间更改状态栏样式

android 沉浸式状态栏(像ios那样的状态栏与应用统一颜色样式)

iOS 7 及更高版本:为每个视图控制器设置状态栏样式