Swift 4.2填坑之StatusBarStyle设置

更新到Swift4.2后,项目里调用UIApplication.shared.statusBarStyle = .light的地方报警告:Setter for 'statusBarStyle' was deprecated in iOS 9.0: Use -[UIViewController preferredStatusBarStyle]

解决办法(默认info.plist已设置View controller-based status bar appearance为NO):

  1. 如果使用了自定义的UINavigationController,在自定义的UINavigationController中重写childForStatusBarHiddenchildForStatusBarStyle两个属性:

    1
    2
    3
    4
    5
    6
    7
    override var childForStatusBarHidden: UIViewController? {
    return self.topViewController
    }

    override var childForStatusBarStyle: UIViewController? {
    return self.topViewController
    }

    如果没有自定义UINavigationController也没关系,扩展UINavigationController就可以了:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    extension UINavigationController {
    override open var childForStatusBarHidden: UIViewController? {
    return self.topViewController
    }

    override open var childForStatusBarStyle: UIViewController? {
    return self.topViewController
    }
    }
  2. 在需要改变状态栏的controller中重写preferredStatusBarStyle:

    1
    2
    3
    override var preferredStatusBarStyle: UIStatusBarStyle {
    return .lightContent
    }

关于为什么要重写childForStatusBarHiddenchildForStatusBarStyle两个属性:

这两个属性默认返回值为nil

当我们调用setNeedsStatusBarAppearanceUpdate的时候,系统会调用Container(容器控制器)的preferredStatusBarStyle这个方法(window?.rootViewControllerpreferred的方法,一般我们用UINavigationController或者UITabBarController来做Container),也就是根本不会调用子控制器(我们所看到的UIViewcontroller)的preferredStatusBarStyle方法。

重写了childForStatusBarHiddenchildForStatusBarStyle后,这两个属性返回的都是当前展示的controller,则调用的statusBarStyle就是当前controller重写的preferredStatusBarStyle了。