I have AuthViewController
that is presenting MainViewController
like so:
let mainVC = MainViewContoller()
mainVC.modalTransitionStyle = .CrossDissolve
authVC.presentViewController(mainVC, animated: true, completion: nil)
I want the AuthViewController
to hide the status bar, but the MainViewController
to show, like so:
AuthViewController {
override func preferredStatusBarStyle() -> UIStatusBarStyle {
return .LightContent
}
override func preferredStatusBarUpdateAnimation() -> UIStatusBarAnimation {
return .Fade
}
override func prefersStatusBarHidden() -> Bool {
return false
}
}
MainViewController {
override func preferredStatusBarStyle() -> UIStatusBarStyle {
return .LightContent
}
override func preferredStatusBarUpdateAnimation() -> UIStatusBarAnimation {
return .Fade
}
override func prefersStatusBarHidden() -> Bool {
return false
}
}
The status bar appears, however the preferredStatusBarUpdateAnimation()
override is ignored. The status bar appears with no animation.
I have only been able to get it to animate by setting prefersStatusBarHidden
on MainViewController
to true
until the viewDidAppear
, then calling this:
UIView.animateWithDuration(0.3) {
self.setNeedsStatusBarAppearanceUpdate()
}
I don't want to have to call this every time. What am I doing wrong?
been searching for a solution to this too. However it seems you got half the solution already. You have to set up the overrides for the variables, but best practice for me was to create a private variable pair for each of the overrides, and have each override return it's respective private var (see bellow). You'd then change up the private variables and call setNeedsStatusBarAppearanceUpdate
.
Plus, you need to set View controller-based status bar appearance
in your info.plist
to YES
. Otherwise, it will still rely on the legacy UIApplication.shared...
methods.
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()
})
})
}
You end up having to tune every view controller, but it seems like it's what you want to do, so hope it helps!