I see that in iOS 9 setStatusBarHidden(_:withAnimation:)
is now deprecated and the documentation says to use [UIViewController prefersStatusBarHidden]
instead but what is the alternative in iOS 9 if I still want to hide the status bar with a slide animation?
Asked
Active
Viewed 2.1k times
43

jacobsieradzki
- 1,108
- 2
- 10
- 32
5 Answers
101
Refer to preferredStatusBarUpdateAnimation
,
Gif
Code
class ViewController: UIViewController {
var isHidden:Bool = false{
didSet{
UIView.animate(withDuration: 0.5) { () -> Void in
self.setNeedsStatusBarAppearanceUpdate()
}
}
}
@IBAction func clicked(sender: AnyObject) {
isHidden = !isHidden
}
override var preferredStatusBarUpdateAnimation: UIStatusBarAnimation{
return .slide
}
override var prefersStatusBarHidden: Bool{
return isHidden
}
}

Leo
- 24,596
- 11
- 71
- 92
-
Mine's not animating even though it's in a aim block. Any ideas? – Hari Honor Sep 29 '15 at 09:22
-
Does it work with "View controller-based status bar appearance" = NO? – Tai Le Oct 27 '15 at 09:07
-
Have not test,but I guess not work when this key is NO – Leo Oct 27 '15 at 09:07
-
1Mime works after set "View controller-based status bar appearance" = YES. Thank you! – Tualatrix Chou Nov 23 '15 at 07:34
-
Worked for me too, major thanks for the animate(withDuration:) tip. I am surprised to know .slide does not animate implicitly over a period of time. – Ian Moses Nov 17 '16 at 04:37
-
1if you need `View controller-based status bar appearance` = NO, this might help: http://stackoverflow.com/a/41294874/611879 – budiDino Dec 23 '16 at 03:49
14
Swift 3
- Computed variables have replaced some functions
- The animate function has updated syntax
class ViewController: UIViewController {
var isHidden:Bool = false
@IBAction func clicked(sender: AnyObject) {
isHidden = !isHidden
UIView.animate(withDuration: 0.5) { () -> Void in
self.setNeedsStatusBarAppearanceUpdate()
}
}
override var preferredStatusBarUpdateAnimation: UIStatusBarAnimation {
return UIStatusBarAnimation.slide
}
override var prefersStatusBarHidden: Bool {
return isHidden
}
}

Felipe Plets
- 7,230
- 3
- 36
- 60

Tim Windsor Brown
- 4,069
- 5
- 25
- 33
13
I have cleaned up Leo's amazing answer a bit by moving the update to didSet
(Swift 3 syntax).
class ViewController: UIViewController {
@IBAction func clicked(sender: AnyObject) {
statusBarHidden = !statusBarHidden
}
var statusBarHidden = false {
didSet {
UIView.animate(withDuration: 0.5) { () -> Void in
self.setNeedsStatusBarAppearanceUpdate()
}
}
}
override var prefersStatusBarHidden: Bool {
return statusBarHidden
}
override var preferredStatusBarUpdateAnimation: UIStatusBarAnimation {
return .slide
}
}

Alex Staravoitau
- 2,222
- 21
- 27
-
1I wish I would remember to use didSet from time to time... I'm just used to my old ways of coding, but this is sooooooo much better :) – budiDino Dec 23 '16 at 03:52
4
if you are coding with objective c, Here is the solution :)(Leo's Objective C version :P thanks man!!!)
declare a variable
bool isHidden;
isHidden = false;//in viewDidload()
and then add this code when you want to hide status bar
isHidden = true;
[UIView animateWithDuration:0.6 animations:^{
[self performSelector:@selector(setNeedsStatusBarAppearanceUpdate)];
}];
after that add this two method
-(UIStatusBarAnimation) preferredStatusBarUpdateAnimation
{
return UIStatusBarAnimationFade;
}
-(BOOL) prefersStatusBarHidden
{ return isHidden;}
Hope your problem will be solve (smile)

Zahid Hasan
- 45
- 7
0
- SWIFT 3 ALTERNATIVE
Hey guys, found a much neater way of going about it for Swift 3, by using a private var pairing with each of the overrides. My original post: https://stackoverflow.com/a/42083459/7183483
but here's the jist of it:
Here's a snippet:
override var preferredStatusBarUpdateAnimation: UIStatusBarAnimation {
get {
return .slide
}
}
private var statusBarStyle : UIStatusBarStyle = .default
override var preferredStatusBarStyle: UIStatusBarStyle {
get {
return statusBarStyle
}
}
private var statusBarStatus : Bool = false
override var prefersStatusBarHidden: Bool {
get {
return statusBarStatus
}
}
which I then could call in a function like so: (this is one of my examples, so disregard the custom function).
func sliderView(sliderView: SliderView, didSlideToPlace: CGFloat, within: CGFloat) {
let val = (within - (didSlideToPlace - sliderView.upCent))/(within)
print(val)
//Where you would change the private variable for the color, for example.
if val > 0.5 {
statusBarStyle = .lightContent
} else {
statusBarStyle = .default
}
UIView.animate(withDuration: 0.5, animations: {
sliderView.top.backgroundColor = UIColor.black.withAlphaComponent(val)
self.coverLayer.alpha = val
self.scroll.backgroundColor = colors.lightBlueMainColor.withAlphaComponent(val)
}, completion: {
value in
//If you do not call setNeedsStatusBarAppearanceUpdate() in an animation block, the animation variable won't be called it seems.
UIView.animate(withDuration: 0.4, animations: {
self.animating = true
//Where you set the status for the bar (your part of the solution)
self.statusBarStatus = false
//Then you call for the refresh
self.setNeedsStatusBarAppearanceUpdate()
})
})
}
-
This is a great solution. I did not think of making the status hidden flag dynamic. – phatmann Feb 16 '18 at 23:46