Update
It looks like this was fixed in iOS 10. The default behavior is to ignore the status bar rules from the presented view controller, unless the presented view controller has modalPresentationCapturesStatusBarAppearance == true or you use one of several built-in view controllers that propagate into the status bar space ( not .custom ).
Basically, the behavior for custom has been changed to default failure, not forced failure.
For iOS 9.x and below
After repeated copying, the internal logic for setting the color of the application status bar is as follows:
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()
The presentation manager property _presentedStatusBarViewController is assigned during presentation based on the value of its private control method _shouldChangeStatusBarViewController() . The default implementation of this method is to return true with _UIAlertControllerPresentationController and several other view controllers that return false.
This means that the most direct way to not change this status bar is to simply add this method to my view controller:
private class SEUIProgressControllerPresentationController: UIPresentationController { @objc func _shouldChangeStatusBarViewController() -> Bool { return false } ... }
Unfortunately, this will not pass the review of the App Store.
Instead of what I am doing, this is a recreation of the logic that will be applied to the view controller in my view controller:
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() } }
source share