更新
看起来这已在 iOS 10 中修复。默认行为是忽略来自呈现的视图控制器的状态栏规则,除非呈现的视图控制器具有modalPresentationCapturesStatusBarAppearance == true
或您使用延伸到状态栏的几个内置呈现控制器之一空间(不是.custom
)。
基本上,自定义行为已更改为默认选择退出而不是强制选择加入。
适用于 iOS 9.x 及更低版本
经过大量挖掘,设置应用程序状态栏颜色的内部逻辑如下所示:
var viewController = window.rootViewController!
while let presentedViewController = viewController.valueForKey("_presentedStatusBarViewController") as? UIViewController {
viewController = presentedViewController
}
while let childViewController = viewController.childViewControllerForStatusBarStyle() {
viewController = childViewController
}
let style = viewController.preferredStatusBarStyle()
视图控制器的属性_presentedStatusBarViewController
是在演示期间根据其演示控制器的私有方法的值分配的_shouldChangeStatusBarViewController()
。此方法的默认实现是返回 true,_UIAlertControllerPresentationController
以及少数其他演示控制器返回 false。
这意味着不更改状态栏的最直接方法就是将此方法添加到我的演示控制器:
private class SEUIProgressControllerPresentationController: UIPresentationController {
@objc func _shouldChangeStatusBarViewController() -> Bool {
return false
}
...
}
不幸的是,这不会通过 App Store 审查。
相反,我正在做的是在我的视图控制器中重新创建将应用于呈现视图控制器的逻辑:
public class SEUIProgressController: UIViewController {
...
public override func preferredStatusBarStyle() -> UIStatusBarStyle {
guard var targetViewController = presentingViewController else {
return .LightContent
}
while let parentViewController = targetViewController.parentViewController {
targetViewController = parentViewController
}
while let childViewController = targetViewController.childViewControllerForStatusBarStyle() {
targetViewController = childViewController
}
return targetViewController.preferredStatusBarStyle()
}
public override func prefersStatusBarHidden() -> Bool {
guard var targetViewController = presentingViewController else {
return false
}
while let parentViewController = targetViewController.parentViewController {
targetViewController = parentViewController
}
while let childViewController = targetViewController.childViewControllerForStatusBarHidden() {
targetViewController = childViewController
}
return targetViewController.prefersStatusBarHidden()
}
}