48

In a ViewController, which I presented modally, I did this:

override func prefersStatusBarHidden() -> Bool {
    return true
}

This used to work, but it no longer works. What's the best way to hide the status bar only for this view controller?

Pang
  • 9,564
  • 146
  • 81
  • 122
TIMEX
  • 259,804
  • 351
  • 777
  • 1,080
  • just check Programtically way [this](http://stackoverflow.com/q/19067899/3388012) – Rushi trivedi Jan 27 '16 at 05:06
  • It's still working fine. If you want to apply the function to all of your View Controllers then consider using inheritance. – Tim Sep 06 '16 at 02:25
  • Possible duplicate of [How to hide a status bar in iOS?](https://stackoverflow.com/questions/12661031/how-to-hide-a-status-bar-in-ios) – Jake Chasan Jul 11 '19 at 15:13
  • 1
    Just go to info.plist and update **View controller-based status bar appearance** to **YES** as mentioned by @lance – Akshay Jadhav Sep 16 '19 at 10:07

15 Answers15

70

For Swift 3 & Swift 4 it has changed to overriding a variable like this:

override var prefersStatusBarHidden: Bool {
  return true
}

If you want to "Update" the state once the view controller is already being displayed, you will need to call:

setNeedsStatusBarAppearanceUpdate()

Please refer to the documentation.

Pochi
  • 13,391
  • 3
  • 64
  • 104
  • 1
    in tabbarcontroller setNeedsStatusBarAppearanceUpdate() not make prefersStatusBarHidden triggered – famfamfam Aug 27 '18 at 03:27
  • @famfamfam Make sure you don't have controller-based status bar appearance disabled in your info.plist. If you do this property is completely ignored. Also, PrefersStatusBarHidden might be getting called in a parent controller instead. It depends on how you organized your view controllers. – Pochi Aug 28 '18 at 03:30
47

For Swift 3 and Swift 4.2 when view going to Appear

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)

    UIApplication.shared.isStatusBarHidden = true
}

when view goint to Dissapear

override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)

    UIApplication.shared.isStatusBarHidden = false
}

It's possible you need set in your info.plist, next line:

View controller-based status bar appearance = NO

enter image description here

gandhi Mena
  • 2,115
  • 1
  • 19
  • 20
21

In your UIViewController:

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)
    UIApplication.shared.isStatusBarHidden = true
}

 override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)
    //It will show the status bar again after dismiss
    UIApplication.shared.isStatusBarHidden = false
}

override var prefersStatusBarHidden: Bool {
    return true
}
anas.p
  • 2,246
  • 19
  • 26
19

In iOS 9, Xcode 7, Swift 2.0, it's back to how it was previously.

override func prefersStatusBarHidden() -> Bool {
        return true
}

In fact Xcode will tell you that

UIApplication.sharedApplication().setStatusBarHidden(true, withAnimation: .None) 

has been deprecated and that you should use the prefersStatusBarHidden method.

Cœur
  • 37,241
  • 25
  • 195
  • 267
Greg
  • 515
  • 1
  • 8
  • 19
  • 8
    If the prefersStatusBarHidden method does nothing, add setNeedsStatusBarAppearanceUpdate() to your viewDidLoad or viewDidAppear method. Depending on what you want to achieve. – Benjamin Aug 25 '16 at 09:03
16

For Swift 3,

override var prefersStatusBarHidden: Bool{
        return true
    }

and add viewDidLoad()

self.modalPresentationCapturesStatusBarAppearance = true
Ali BOZOĞLU
  • 188
  • 1
  • 5
8

You can achieve this by simply overriding prefersStatusBarHidden property in your ViewController as shown below :

override var prefersStatusBarHidden: Bool {
   return true
}

Screenshot added

This works for Swift 3/4.

Jayprakash Dubey
  • 35,723
  • 18
  • 170
  • 177
4

Hide Status Bar smoothly by just using UIAnimation and stored property.

Swift 3+

  var statusBarState = false
    override var prefersStatusBarHidden: Bool{
        return statusBarState
    }

And then in viewWillAppear

  override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        statusBarState = true
        UIView.animate(withDuration: 0.30) {
            self.setNeedsStatusBarAppearanceUpdate()
        }
    }

enter image description here

Rizwan Mehboob
  • 1,333
  • 17
  • 19
3

For those still struggling, the below works for iOS9.

You update the rootViewController prefersStatusBarHidden function by calling it from your individual child/grandchild viewControllers. This works where you add childViewControllers directly to your rootViewController.

You don't need to set anything in the info.plist, but setting setting 'statusBarIsInitiallyHidden' works independently of the below.

First, in your rootViewController, add the following:

-(void)viewDidLoad {
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(updateStatusBarAppearance:) name:@"kStatusBarAppearance" object:nil]; 
}
-(void)updateStatusBarAppearance:(NSNotification *)n {
    statusBarIsHidden = [n.object boolValue];
    [self setNeedsStatusBarAppearanceUpdate];
}
-(UIStatusBarStyle)preferredStatusBarStyle {
    return UIStatusBarStyleLightContent; //optional
}
-(BOOL)prefersStatusBarHidden{
    return statusBarIsHidden;
}

Then, in the single view controller where you want to hide the status bar, call this:

-(void)viewDidLoad {
    [[NSNotificationCenter defaultCenter] postNotificationName:@"kStatusBarAppearance" object:[NSNumber numberWithBool:true]];
}
-(void)popSelf {
    [[NSNotificationCenter defaultCenter] postNotificationName:@"kStatusBarAppearance" object:[NSNumber numberWithBool:false]];
}
Johnny Rockex
  • 4,136
  • 3
  • 35
  • 55
2

When all else fails (as it did for me) Swift 4.1

No editing of .plist required. And AppStore will approve it

(UIApplication.shared.value(forKey: "statusBarWindow") as? UIWindow)?.isHidden = false
Sentry.co
  • 5,355
  • 43
  • 38
2

A late answer but if you need an alternative solution you can use this:

public func ShowStatusBar() {

    let statusBarWindow = UIApplication.shared.value(forKey: "statusBarWindow") as? UIWindow
    UIView.animate(withDuration: 0.3) {
        statusBarWindow?.alpha = 1
    }
}

public func HideStatusBar() {

    let statusBarWindow = UIApplication.shared.value(forKey: "statusBarWindow") as? UIWindow
    UIView.animate(withDuration: 0.3) {
        statusBarWindow?.alpha = 0
    }
}
Hakan Baybas
  • 104
  • 5
1

You can use

override public func viewWillAppear(animated: Bool) {
    super.viewWillAppear(animated)
    // hide status bar
    dispatch_async(dispatch_get_main_queue(), {
        if let window = UIApplication.sharedApplication().keyWindow {
            window.windowLevel = UIWindowLevelStatusBar + 1
        }
    })

}

override public func viewWillDisappear(animated: Bool) {
    super.viewWillDisappear(animated)
    // Show status bar
    dispatch_async(dispatch_get_main_queue(), {
        if let window = UIApplication.sharedApplication().keyWindow {
            window.windowLevel = UIWindowLevelNormal
        }
    })

}
Carlos Chaguendo
  • 2,895
  • 19
  • 24
1

Use this code:

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)

    UIApplication.shared.isStatusBarHidden = true
}

if this code doesn't work, you need to add this key in the info.plist

View controller-based status bar appearance - NO

Diego Carrera
  • 2,245
  • 1
  • 13
  • 16
1

I'm using Xcode Version 9.2 / Swift 3.2 / iOS 11

I got this answer form BADCloud although I'm not sure why it didn't work for him.

Anyway it worked for me for a specific view controller.

The difference between this answer and the other answers on here is that in my info.plist when I initially had View controller-based status bar appearance - NO with the 2 statusBar methods below it didn't work but when I changed it to Yes is worked with both of them.

In the info.plist change: View controller-based status bar appearance - YES enter image description here

In the view controller you want it changed in add:

override func viewDidLoad() {
        super.viewDidLoad()

        // add this in ViewDidLoad
        setNeedsStatusBarAppearanceUpdate()
}

// add this underneath ViewDidLoad
override var prefersStatusBarHidden: Bool {
  return true
}
Lance Samaria
  • 17,576
  • 18
  • 108
  • 256
  • You can skip code written in viewDidLoad(). setting flag in info.plist and overriding prefersStatusBarHidden is enough. Nice work bro, thanks for the help – Akshay Jadhav Sep 16 '19 at 10:03
  • Ok thanks for the advice about the viewDidLoad code. I haven’t touched that project in over a year but I’m getting back to it in a couple of months. Once I try it if it works I’ll take the code out. Thanks for the advice. Cheers! – Lance Samaria Sep 16 '19 at 18:52
0

Complete solution for iOS 11 and Swift 4, giving you full control from your program.

var statusBarHidden : Bool?

override var prefersStatusBarHidden: Bool {
    get {
        if let status = statusBarHidden { return status } else { return false }
    }
    set(status) {
        statusBarHidden = status
        setNeedsStatusBarAppearanceUpdate()
    }
}

Now you can simply show or hide the status bar by setting the property from your code. I tested it like this:

@IBAction func Show(_ sender: Any) {
    prefersStatusBarHidden = false
}

@IBAction func Hide(_ sender: Any) {
    prefersStatusBarHidden = true
}

Works like a charm.

-1
UIApplication.sharedApplication().setStatusBarHidden(true, withAnimation: .None) 

and when you want it back in a separate VC:

UIApplication.sharedApplication().setStatusBarHidden(false, withAnimation: .None) 
jasonnoahchoi
  • 871
  • 5
  • 16