22

I am trying to hide status bar in one of my UIViewControllers (Swift 4).

  • Firstly, I set View controller-based status bar appearance to YES in Info.plist.

  • I overrode the prefersStatusBarHidden property in my controller:


override var prefersStatusBarHidden: Bool {
     return true
}

  • And in viewDidLoad(), I added setNeedsStatusBarAppearanceUpdate() function to force the prefersStatusBarHidden property to be read.

After all that, I still see the status bar on that UIViewController.

Can someone help me, please?

Tamás Sengel
  • 55,884
  • 29
  • 169
  • 223
Dragisa Dragisic
  • 731
  • 2
  • 9
  • 19

15 Answers15

24

You can hide the status bar in any or all of your view controllers just by adding this code:

override var prefersStatusBarHidden: Bool {
     return true
   }

Any view controller containing that code will hide the status bar by default.

If you want to animate the status bar in or out, just call setNeedsStatusBarAppearanceUpdate() on your view controller – that will force prefersStatusBarHidden to be read again, at which point you can return a different value. If you want, your call to setNeedsStatusBarAppearanceUpdate() can actually be inside an animation block, which causes the status bar to hide or show in a smooth way.

Viraj Padsala
  • 1,388
  • 1
  • 13
  • 31
  • I tried all of that, even UIApplication.shared.isStatusBarHidden = true in viewDidLoad(), but status bar is still there...I read swift 4 change log and there is nothing about changing prefersStatusBarHidden.. – Dragisa Dragisic Oct 03 '17 at 11:47
  • What I did on my Swift 4 project was only add the override above and nothing else and it worked. Don't need to change Info.plist file and don't need to call setNeedsStatusBarAppearanceUpdate() – ffabri Oct 04 '17 at 03:04
  • Works for me. I didn't touch the plist. Just copy and pasted the code above within the UIViewController subclass. – Moondra Aug 10 '18 at 22:58
8

You probably found your own solution to this already, but I got it working this way:

override func viewWillAppear(_ animated: Bool) {
    // Sets the status bar to hidden when the view has finished appearing
    let statusBar: UIView = UIApplication.shared.value(forKey: "statusBar") as! UIView
    statusBar.isHidden = true
}

override func viewWillDisappear(_ animated: Bool) {
    // Sets the status bar to visible when the view is about to disappear
    let statusBar: UIView = UIApplication.shared.value(forKey: "statusBar") as! UIView
    statusBar.isHidden = false
}
MachTurtle
  • 220
  • 3
  • 10
  • 4
    This is some risky code... if Apple were for some reason to change the subclass (I would not be surprised, they changed crazier things in the past), crash boom bang – RyanG May 21 '18 at 16:51
  • If you use the null operator instead the worst case scenario is that it will appear. if let statusBar: UIView = UIApplication.shared.value(forKey: "statusBar") as? UIView { statusBar.isHidden = false } – Joel Teply Jun 29 '18 at 18:07
5

If you are presenting the view controller modally, try

viewController.modalPresentationCapturesStatusBarAppearance = true
rollstuhlfahrer
  • 3,988
  • 9
  • 25
  • 38
Alok Sahay
  • 173
  • 3
  • 7
4

Try setting "View controller-based status bar appearance" flag in Info.plist to YES. This will force app to call prefersStatusBarHidden: Bool property on every view controller.

View controller-based status bar appearance flag

Halyna Rubashko
  • 605
  • 5
  • 7
4

Although some implementations are cleaner such as:

UIApplication.shared.isStatusBarHidden = true

There are some weird clipping animations during transitions. Although more verbose, I prefer @MachTurtle's solution:

override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(true)
        if let statusBar: UIView = UIApplication.shared.value(forKey: "statusBar") as? UIView{
        statusBar.isHidden = true
        }
}

override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(true)
    let statusBar: UIView = UIApplication.shared.value(forKey: "statusBar") as! UIView
    statusBar.isHidden = false
}

Try it out, works great for me.

Umair_UAS
  • 113
  • 1
  • 10
Creeptosis
  • 176
  • 1
  • 4
  • 6
    This is some risky code... if Apple were for some reason to change the subclass (I would not be surprised, they changed crazier things in the past), crash boom bang – RyanG May 21 '18 at 16:51
1

Use the following code UIApplication.shared.isStatusBarHidden = true

this is the only thing that I found that is working in iOS11. you can write in didFinishLaunchingWithOptions or in 'viewWillAppear' of you BaseViewController Enjoy.

nitish005
  • 106
  • 11
1

As you said, you are using UINavigationController to navigate to your custom view controller. I suppose you have set your Custom View controller as the root view of your UINavigationController. In this case overriding var prefersStatusBarHidden in your custom view controller won't work but you will have to subclass your UINavigation Controller and override the property there as shown below:-

class CustomNavigationController: UINavigationController {

    override var prefersStatusBarHidden: Bool {
        return true
    }

}
Shayeeb
  • 21
  • 5
1

I discovered that prefersStatusBarHidden wasn't being called in my view controller because I was using a custom container view and I needed to forward the status bar hiding responsibility to the child view controller. Implementing var childForStatusBarHidden: UIViewController? { return childViewController } in the container view controller fixed if for me.

Tylerc230
  • 2,883
  • 1
  • 27
  • 31
1

When you try to overload statusbar properties for ViewController which in UINavigationStack - you need make extension below

extension UINavigationController {
  override open var childForStatusBarStyle: UIViewController? {
    return self.topViewController
  }
}

then your overloaded properties will became active

Leonif
  • 466
  • 4
  • 17
1

I was searching for it and the one work for me is

Swift 5

override var prefersStatusBarHidden: Bool {
  return true
 }
Noman Haroon
  • 185
  • 1
  • 11
0

Try checking Hide Status Bar under the General section of your project's settings.

Hide status bar option under Project settings/General

Tamás Sengel
  • 55,884
  • 29
  • 169
  • 223
0

None of these worked for me either working on a converted project in iOS 11. Here's what I did. I added this code in the AppDelegate

func application(_ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey : Any]? = nil) -> Bool
{
    application.isIdleTimerDisabled = true
    application.isStatusBarHidden = true
    return true
}
changhwan
  • 1,000
  • 8
  • 22
0

Just change "Top Space to" constraint of your view from Safe area to Superview. And it will drag your view under the Status bar so there is will be no need to hide it![enter image description here]1

Vitya Shurapov
  • 2,200
  • 2
  • 27
  • 32
0

Need to write the code in the container view controller if it is a child view controller

     override var prefersStatusBarHidden: Bool {
      return true
     }
Jin
  • 665
  • 1
  • 7
  • 15
0

Add this to your info.plist

<key>UIStatusBarHidden</key>
    <true/>
Ali A. Jalil
  • 873
  • 11
  • 25