设置statusbarStyle(在iOS 9.0中已弃用)

44

刚刚下载了新的xCode 10.0,发现自iOS 9.0起就已将旧的statusBarStyle弃用。

警告:'statusBarStyle'的Setter在iOS 9.0中被废弃:使用-[UIViewController preferredStatusBarStyle]。

废弃代码:UIApplication.shared.statusBarStyle = .default

我尝试使用 self.preferredStatusBarStyle,但发现该属性只是getter。那么有人知道如何设置 statusBarStyle 吗?


编辑

我想在一个函数内更改 statusBarStyle,让用户可以在不同的主题之间切换。例如:

func changeStatusBar(toDarkMode: Bool) {
    if toDarkMode {
        // Set to light statusBarStyle
    } else { 
        // Set to default
    }
}

请参考以下链接以获取帮助:https://dev59.com/7lkT5IYBdhLWcg3wV-GZ。 - Anbu.Karthik
6个回答

46
Info.plist 中添加 View controller-based status bar appearance NO,并在 Deployment Info 中选择 Light 作为状态栏样式。 enter image description here

5
这是您首次设置的方法。如果您想在应用程序运行期间在深色和浅色之间切换,这就是问题所在。 - Jacob Ahlberg
2
不,这不是唯一的方法。向上滚动到@MdRashedPervez的答案,您会看到另一种更改不同视图控制器状态栏的方法。 - Jacob Ahlberg
@JacobAhlberg 不知道为什么,但这是我让状态栏变成浅色的唯一方法。我尝试了MdRashedPervez的解决方案,但它对我不起作用。 - Pavlos
你是否正在使用导航控制器? - Jacob Ahlberg
2
我刚试了一下@CryingHippos的答案,效果很流畅。我不得不使用UINavigationController的扩展,并返回我想要的样式。来试试吧! - Jacob Ahlberg
显示剩余2条评论

35

使用现有的代码设置darkMode变量,然后在计算变量中使用它,系统会期望这样做:

var darkMode = false
override var preferredStatusBarStyle : UIStatusBarStyle {
    return darkMode ? .default : .lightContent
}

根据情况,您可能需要强制刷新屏幕才能使其生效。您可以通过以下调用来实现:

setNeedsStatusBarAppearanceUpdate()

1
看起来不错,但即使我使用这行代码,statusBarStyle也没有更新。我在darkMode布尔值中使用了一个didSet闭包,它会更新statusBarAppearance。每当我更改布尔值时,它都会被调用。但是statusBarStyle没有改变。你有什么线索吗? - Jacob Ahlberg
你是在根视图控制器中设置这个吗?请参阅苹果文档中的讨论:https://developer.apple.com/documentation/uikit/uiviewcontroller/1621433-childforstatusbarstyle - Paul King
@paulking 我正在使用相同的方法,但在 iPhone XS、XR 和 XS Max 上,默认的启动(闪屏)界面没有显示状态栏的浅色内容。 - BalKrishan Yadav
@BalKrishanYadav,启动/闪屏屏幕不执行任何代码,在这种情况下,您需要在“常规/部署信息”下设置应用程序目标的“状态栏样式”。 - Paul King
正如 @paulking 建议的那样,将其设置在 rootviewcontroller 中就可以解决问题。 - James Rochabrun
如果您使用导航控制器(许多应用程序都这样做),请使用CryingHippo在答案中提到的扩展,否则此操作将无法正常工作。 - Ben

27

Swift4 中,您可以在ViewController中的viewDidLoad()下使用以下代码块-

override var preferredStatusBarStyle : UIStatusBarStyle {
    return .lightContent
}

1
我实际上在两个不同的主题(浅色和深色)之间切换,因此我必须在函数中更改statusBarStyle。你有任何线索吗? - Jacob Ahlberg
在您的函数中为两个不同的主题设置标记,例如对于主题1设置标记1,然后如果它获得标记1,则会显示状态栏亮度。对于其他主题也是如此。 - Rashed
@Md Rashed Pervez,我已经添加了你上面的代码,但似乎没有任何改变。 - icekomo
@MD Rashed Pervez,我已经这样做了。我还读到拥有导航控制器可能会有所不同。你知道这方面的情况吗? - icekomo
@MD Rashed Pervez,感谢您的视频。我按照步骤操作了,但自动完成功能没有给我使用他所使用的那个函数的选项。是从视频发布到现在有什么变化吗? - icekomo
显示剩余5条评论

13

如果您使用UINavigationController,您可能还想使用以下代码:

extension UINavigationController {
   open override var preferredStatusBarStyle: UIStatusBarStyle {
      return topViewController?.preferredStatusBarStyle ?? .default
   }
}

问题在于setNeedsStatusBarAppearanceUpdate() 不会调用子视图的preferredStatusBarStyle


如果我使用编辑菜单下的嵌入式导航控制器,我应该把它放在哪里? - icekomo

5

我尝试了其他建议都不起作用。最终我通过以下方法解决了问题:

  1. Setting:

    override var preferredStatusBarStyle : UIStatusBarStyle {
        return .lightContent
    }
    
  2. Calling:

    setNeedsStatusBarAppearanceUpdate()
    

2
我的解决方案是这样的: 从导航控制器创建一个扩展:
extension UINavigationController {
    open override var preferredStatusBarStyle: UIStatusBarStyle {
        if let topViewController = presentedViewController{
            return topViewController.preferredStatusBarStyle
        }
        if let topViewController = viewControllers.last {
            return topViewController.preferredStatusBarStyle
        }

        return .default
    }
}

如果您有一个视图控制器,它具有与应用程序不同的样式,您可以进行以下操作:

Original Answer翻译成"最初的回答"

并且如果您有一个视图控制器,其样式将与应用程序的样式不同,您可以这样做

var barStyle = UIStatusBarStyle.lightContent
override var preferredStatusBarStyle: UIStatusBarStyle{
    return barStyle
}

假设您的应用程序状态样式为.default,并且您希望此屏幕为.lightContent,那么barStyle将采用.lightContent作为其默认值,这将更改状态栏样式为lightContent,然后确保在viewWillDisappear时再次将barStyle更改为应用程序状态栏样式,即.default这对我很有效。

不要在扩展中覆盖方法。这是未定义的行为,文档指出您不应该这样做。 - rmaddy

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