0

I have a problem when it comes to the status bar and hiding it.

The setup

I have a BaseViewController that has a slide out menu. This BaseViewController is also the root controller of the application [as set inside AppDelegate]:

window = UIWindow()
window?.makeKeyAndVisible()
window?.rootViewController = BaseController()

As soon as I select a menu item the BaseViewController is populated by the corresponding ViewController [after I embed it into a navigation controller].

Menu item A: ViewControllerA

Menu item B: ViewControllerB

Menu item C: ViewControllerC

Say that I select the Menu Item A (the following code takes place inside BaseViewController):

let activeVC = UINavigationController(rootViewController: ViewControllerA())
view.addSubview(activeVC.view)
addChild(activeVC)

When I select another menu item (say item B), I first remove the previous active view controller (in this case item A) and then I add the ViewControllerB the same way as I did with ViewControllerA:

This is how I remove the previous active view controller:

activeVC.view.removeFromSuperview()
activeVC.removeFromParent()

Manipulating the status bar in each view controller separately:

I set the View controller-based status bar appearance to YES in plist control the appearance of the status bar in every view controller:

enter image description here

Then I go into the ViewController I want to hide the status bar and I add the following code:

override var prefersStatusBarHidden: Bool {
    return true
}

The problem

If I want to hide the status bar inside any of the ViewController A, B, or C, I can't. Overriding the prefersStatusBarHidden and setting it to "true" will do nothing.

If I override the prefersStatusBarHidden and setting it to "true" into the BaseViewController, then the BaseViewController and also any of the ViewController A, B, and C will hide the status bar.

What I want

I want to be able to hide the status bar on ViewControllerB without hiding it on the rest. Also a million dollars, but I will settle with the solution!

Thanks in advance!

4
  • 1
    I think you may need to manually call setNeedsStatusBarAppearanceUpdate (developer.apple.com/documentation/uikit/uiviewcontroller/…) Commented Apr 23, 2019 at 21:14
  • 1
    Please don't show pictures of code. Replace the pictures of code with the actual code, just like you have in other parts of your question. Commented Apr 23, 2019 at 21:14
  • @oyvindhauge i did this inside ViewControllerB inside an animation block but it did not help. Maybe i did it wrong. How would you setup this? Commented Apr 23, 2019 at 21:31
  • @rmaddy i will fix it as soon as i find myself a laptop :) Commented Apr 23, 2019 at 21:36

2 Answers 2

3

You'll need to override var childForStatusBarHidden: UIViewController? for BaseController and for UINavigationController. For example:

override var childForStatusBarHidden: UIViewController? {
    return children.first
}

and

extension UINavigationController {

    open override var childForStatusBarHidden: UIViewController? {
        return topViewController
    }
}
Sign up to request clarification or add additional context in comments.

2 Comments

Your response guided me to the right track and I figured it out. At first, I went into the BaseController and added what you suggested with a twist: I used "return children.last". Then inside the ViewControllerB I set the "prefersStatusBarHidded" to "true". But here is the catch: If your VC is embedded inside a navigation controller, and if you are using a device with no bezels (such as iPhone X) you need to remove the navigation bar for the status bar to be hidden. So I also used navigationController?.setNavigationBarHidden(true, animated: false). And now it works!
This is not strictly true. It is not necessary to hide the navigation bar to get the status bar hidden, though doing so likely triggers a status bar refresh. As other commenters have pointed out you can trigger a status bar refresh directly by calling setNeedsStatusBarAppearanceUpdate
0

I had a use case where I had to present a ViewController nested inside a navBar controller the only way which worked for me is adding the following on initilization of a presented ViewController.

modalPresentationCapturesStatusBarAppearance = true

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.