如何更改状态栏样式 - iOS 12

26

我需要根据背景颜色更新每个视图控制器上的状态栏样式(就像UINavigationController自动处理的那样)。

已经尝试了在stackoverflow上描述的所有选项(在info.plist中将View controller-based status bar appearance设置为 YES ),但对我都不起作用。

我正在使用Xcode 10 beta 6和Swift 4.2,针对iOS 12。


可能是[设置statusbarStyle(在iOS 9.0中已弃用)]的重复问题(https://dev59.com/zFUL5IYBdhLWcg3wM1ry)。 - Jacob Ahlberg
6个回答

34

Swift 4+, iOS 12+

View controller-based status bar appearance现在需要在info.plist中设置为YES,因为UIKit不再希望我们通过UIApplication.shared编辑状态栏样式。现在状态栏样式是基于视图控制器的。

然后,如果您想要在应用程序级别应用更改,请在适当的容器视图控制器中(最好是根控制器)重写preferredStatusBarStyle...

override var preferredStatusBarStyle: UIStatusBarStyle {
    return .lightContent
}

...并且这将传播到其下面的所有视图控制器。如果您想要在每个视图控制器中编辑状态栏样式,则对每个视图控制器应用此覆盖。

如果状态栏样式在运行时发生更改,则需要从容器/根视图控制器或该特定视图控制器的任何位置调用setNeedsStatusBarAppearanceUpdate(),否则不需要。


这个!所有其他关于将“View controller-based status bar appearance”设置为“NO”的答案都不起作用 - Caio
我在视图控制器之间使用自定义过渡效果。由于iOS 12中状态栏的动画出现问题,我使用了从浅色到默认色以及相反方向的平滑过渡效果。在iOS 12中,状态栏在过渡之前会闪烁一小段时间。你知道发生了什么变化吗? - Evgeny
如果UIApplication的rootViewController是tabbarvc或navigationvc(容器视图控制器),那么这个vc将接管控制,您可以重写childViewControllerForStatusBarStyle方法并返回您想要接管控制的控制器。例如,tabbar返回selectedViewController(navigationvc),而navigationvc返回其topViewController - Jiangshi Fresh

29

info.plist 中把 View controller-based status bar appearance 设置为 NO,然后在每个视图控制器中重写 preferredStatusBarStyle

override var preferredStatusBarStyle: UIStatusBarStyle {
    return .lightContent
}

在您的视图控制器中调用setNeedsStatusBarAppearanceUpdate()(例如在viewDidLoad()中)。


1
你说得对!但自从iOS 9以后,那个方法已经被弃用了。但是我错过了什么吗?我将值设置为info.plist。然后在特定视图控制器的viewDidLoad()中添加了这行代码。但是没有看到任何变化。 - Tomáš Pánik
@TomášPánik 你是否在调用 self.setNeedsStatusBarAppearanceUpdate() - ielyamani
当我在使用Xcode时,它告诉我“iOS 9.0中'statusBarStyle'的setter已被弃用:请使用-[UIViewController prefferedStatusBarStyle]”。你知道怎么做吗?请注意,出现了另一个错误:“属性不覆盖其超类的任何属性”,而我正在使用override var prefferedStatusBarStyle ... - Tomáš Pánik
8
请注意:此方法仅适用于 plist 布尔值设置为 YES。 - Tomáš Pánik
4
如果使用模态呈现的视图控制器,您可能需要在要模态呈现的视图控制器上设置 myViewController.modalPresentationCapturesStatusBarAppearance = true。除非我这样做了,否则我无法使此答案起作用。info.plist键已设置为yes - Chris
显示剩余8条评论

15

如果你在info.plist中设置了View controller-based status bar appearanceYES,并且你的视图控制器嵌入到UINavigationController中,则导航控制器将负责更新栏样式(通过navigationController.navigationBar.barStyle),preferredStatusBarStyle属性将被忽略。


11
我有Xcode 10.2,并发现与您一样,在info.plist中将“View controller-based status bar appearance”设置为“YES”不会改变状态栏的样式。

然而,我发现在info.plist文件中更改两个键就可以轻松更改状态栏的颜色,不需要任何额外的编码。

以下是我为自己解决此问题所做的操作:
在info.plist文件的顶部行“Information Property List”上悬停时,会出现一个小圆形“+”按钮。点击此按钮并滚动查找以下键。

View controller-based status bar appearance [将此值设置为] NO
Status bar style [将此值设置为] UIStatusBarStyleLightContent

注意:在值列表中无法找到可选择的UIStatusBarStyleLightContent选项,必须键入值框中。

info.plist

我希望这能对您或寻找此问题答案的其他人有所帮助。

1
但是 UIStatusBarStyleLightContent 会根据内容在每个 ViewController 上更改状态栏颜色吗? - Tomáš Pánik
1
哦,哇,我没有看到问题中的那部分哈哈,看来我需要更加注意这里的问题。不,它不会根据内容进行更改。它只会为整个项目更改它们。谢谢你指出来! - Jim Bray

2
如果您使用导航控制器,您将需要这个:
final class LightNavigationController: UINavigationController {
    override var preferredStatusBarStyle: UIStatusBarStyle {
        return .lightContent
    }
}

-1
override func viewDidLoad(){
    super.viewDidLoad()

    navigationController?.navigationBar.barStyle = .default
}

override var prefersStatusBarHidden: Bool {
    return true
}

我在同一屏幕上应用了滚动视图,通过这段代码能够解决状态栏问题。


这段代码没有任何关于更改状态栏样式的操作! - Kawe

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接