33

I have a UITabViewController -> UINavigationController -> UIViewController and want to hide and unhide the statusBar. when I call setNeedsStatusBarAppearanceUpdate() the method prefersStatusBarHidden is not called.

func fadeOutStatusBar (notification: NSNotification) {
    statusBarHidden = true
    self.setNeedsStatusBarAppearanceUpdate()
}

func fadeInStatusBar (notification: NSNotification) {
    statusBarHidden = false
    self.setNeedsStatusBarAppearanceUpdate()
}

override func prefersStatusBarHidden() -> Bool {
    return statusBarHidden
}
Leo
  • 24,596
  • 11
  • 71
  • 92
Md1079
  • 1,360
  • 1
  • 10
  • 28
  • 1
    This has discussed in so many times in OS. see [this](http://stackoverflow.com/questions/18059703/cannot-hide-status-bar-in-ios7) – Jamil Nov 05 '15 at 10:25
  • only the accepted answer is the opposite to mine – Md1079 Nov 05 '15 at 10:28
  • @Md1079, that is because your question was not very clear - it sounded like you were asking how to do that in just one view, so most people gave you solutions to just tweak one view, while Nghia Luong responded with both options that could help. – Natalia Jun 17 '16 at 08:36
  • You might want to check the following answer: https://stackoverflow.com/questions/50714171/iphonex-not-call-prefersstatusbarhidden/52210933#52210933 – Claus Sep 06 '18 at 19:28

9 Answers9

40

Firstly, View controller-based status bar appearance in the .plist file must be set to YES.

  • If you want status bar to be hidden in the whole app:

For Objective-C:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    [application setStatusBarHidden:YES];

    return YES;
}

For Swift:

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject:AnyObject]?) -> Bool {
    application.statusBarHidden = true

    return true
}
  • If you want status bar is disappeared in Specify View Controller, in .m file, just implement:

For Objective-C:

- (BOOL)prefersStatusBarHidden {
    return YES;
}

For Swift:

override func prefersStatusBarHidden() -> Bool {
    return true
}
Iulian Onofrei
  • 9,188
  • 10
  • 67
  • 113
Nghia Luong
  • 790
  • 1
  • 6
  • 11
24

Figured it out. in info.plist file: view controller-status bar appearance should be set to YES

Md1079
  • 1,360
  • 1
  • 10
  • 28
  • 5
    Your answer here would be more useful if you explained in more detail what this will achieve Local status bar hiding? Globally across the app? (FYI your answer shows how to do it globally - while your initial question seems to ask how to do it for 'a view') This is confusing and unclear. I think you should accept Nghia's answer for this question. – Natalia Jun 17 '16 at 08:50
  • Yes, it let the viewcontrollers handle the status bar. Otherwise, the delegate is never called. – Medhi Dec 18 '17 at 13:42
16

For swift 3, first, make sure that View controller-based status bar appearance is set to YES in your Info plist file

screenshot

And then just add this to your view controller:

override var prefersStatusBarHidden: Bool {
    get {
        return true
    }
}

I hope this helps people in the future.

Iulian Onofrei
  • 9,188
  • 10
  • 67
  • 113
Barrett
  • 323
  • 5
  • 11
11

Maybe not a solution to the OP problem, but what could also be the cause for prefersStatusBarHidden not being called is if you have used a second window in your app delegate, eg for displaying a splash screen, and you did not hide it after the splash was shown - then that window gets the events that lead to calling these functions.

TheEye
  • 9,280
  • 2
  • 42
  • 58
11

When we nested the UINavigationController, our AppDelegate. Window. RootViewController Usually we create navigationController when first will call in the navigationController childViewControllerForStatusBarHidden function, because the default returns nil, then is called navigationController prefersStatusBarHidden function itself, So the status bar that we set in viewController through the prefersStatusBarHidden function will not be called, so it won't work. So we're going to create our own one that inherits from the NavigationController,in this subclass ChildViewControllerForStatusBarHidden function.

If you are using a UINavigationController as your window.rootViewController from your AppDelegate, then you might want to extend UINavigationController in order to call its topViewController's prefersStatusBarHidden:

class YourNavigationController: UINavigationController {
    override var childForStatusBarHidden: UIViewController? {
        return topViewController
    }
}
Bhargav Rao
  • 50,140
  • 28
  • 121
  • 140
JackySong
  • 154
  • 1
  • 4
  • Just saved me from hitting my head against the wall! Thanks!! – christostsang Jul 28 '21 at 09:09
  • Me too. I was going crazy. Nobody has mentioned this. Thanks @JackySong – Houman Mar 23 '22 at 17:20
  • Same here on Swift 5. Tried everything else, and this was what finally did it. If your app subclasses UINavigationController make sure you try this + overriding `prefersStatusBarHidden` in your ViewController. – Jake Z Aug 26 '23 at 05:27
2

Property prefersStatusBarHidden is being called on the root view controller of the current view controller.

This means that if your app is based on a UISplitViewController for example, you must implement the property in a custom UISplitViewController class.

Ely
  • 8,259
  • 1
  • 54
  • 67
1

For Swift 4.2 iOS 12

Assuming you have a ViewController contained within UINavigationController. Create your own Subclass of UINavigationController and include in it:

override var preferredStatusBarStyle: UIStatusBarStyle {
    return .lightContent
}

Make sure info.plist sets View Controller based setting of status bar

Nick
  • 138,499
  • 22
  • 57
  • 95
idej1234
  • 63
  • 6
1

If you have other window not hidden, the method not be called. Just hide other window, it will work as you wish

xiao333ma
  • 81
  • 7
0

You just simply need to hide the navigation controller and the statusBar will also hidden.

try this viewDidLoad example

override func viewDidLoad() {
    super.viewDidLoad()
    navigationController?.setNavigationBarHidden(false, animated: false)
}
Farras Doko
  • 307
  • 4
  • 11