When I run my application, you can see the navigation bar animates in very quickly, it seems like I only catch the end. The animation also seems like it slides down from the top. I have written no code for it to do this! That's why it's weird!
Here's the weirder thing. In the info.plist if I set "View controller-based status bar appearance" to "NO" this does NOT happen. It only happens when I set it to "YES"!
I want "View controller-based status bar appearance" to be set to "YES" because I want to be able to turn it off on specific view controllers using:
override func prefersStatusBarHidden() -> Bool {
return true
}
Please help!
Pay attention to View controller-based status bar appearance in plist file, it means, that you will determine logic of status bar inside your app.
Do you assume that UIStatusBar and UINavigationBar are the same?
Definetly not.
So you function:
override func prefersStatusBarHidden() -> Bool {
return true
}
is hiding status bar (20px bar with battery, clocks and mobile cell).
If you want to change it's animation you should use:
override func preferredStatusBarUpdateAnimation() -> UIStatusBarAnimation {
return .None
}
If you want to hide UINavigationBar in some view controller, you should call inside view controller:
navigationController?.setNavigationBarHidden(true, animated: false)
Related
I have a UITabBarController as the root view controller. Each tab has a view controller embedded inside of a navigation controller. My navigation bars are a dark color so I need the status bar to be set to .lightContent. I also need to hide the status bar dynamically.
If I set "View controller-based status bar appearance" to "NO", I can set the status bar correctly to ".lightContent", but I cannot hide the status bar dynamically.
If I set "View controller-based status bar appearance" to "YES", the status bar will only set to ".lightContent" if a navigation bar is NOT present.
This is what I use in each view controller to show or hide the status bar:
var shouldHideStatusBar: Bool = false {
didSet { self.setNeedsStatusBarAppearanceUpdate() }
}
override var prefersStatusBarHidden: Bool { return shouldHideStatusBar }
override var preferredStatusBarUpdateAnimation: UIStatusBarAnimation { return .slide }
override var preferredStatusBarStyle: UIStatusBarStyle { return .lightContent }
I have also tried:
navigationController?.navigationBar.barStyle = .black
There must be something I am missing in order to set the status bar to .lightContent and still be able to dynamically show and hide the status bar.
Resulted to using a deprecated method:
UIApplication.shared.setStatusBarHidden(true, with: .slide)
Not ideal, but works. Hopefully, someone has a solution without relying on a deprecated method.
You have to bubble these values up through your view hierarchy. For instance, your tabBarController should be asking its selectedViewController what its value for prefersStatusBarHidden is then your navigationController needs to ask its topViewController what its value for prefersStatusBarHidden is. This way when prefersStatusBarHidden is called on the tabBarController it relays back what the top most view controller wants to do with the status bar.
I need a white status bar for my main initial ViewController, but also be able to hide it in another ViewController. I can do one or the other, but not both at the same time. Any suggestions?
I set it to white by setting
View controller-based status bar appearance key to NO in the
Info.plist
override func preferredStatusBarStyle() -> UIStatusBarStyle {
return .LightContent
}
And to hide it (on another ViewController presented modally) I do,
override func prefersStatusBarHidden() -> Bool {
return statusBarHidden
}
however it won't hide unless I remove the key I previously added to the Info.plist, but if I remove the key, then the status bar goes back to black.
EDIT-MY Solution:
The View controller classes were not working in my case because I have the main view controller embedded in a navigation controller, my fix was to override the same methods but for the navigation controller instead of the view controller in question.
extension UINavigationController {
public override func preferredStatusBarStyle() -> UIStatusBarStyle {
return .LightContent
}
}
If you add
View controller-based status bar appearance key to NO in the Info.plist
You should use [UIApplication setStatusBarHidden:withAnimation:] and [UIApplication setStatusBarStyle:animated:] to change to the statusbar's appearance. Your method won't be called
As it is said in apple's document:
UIViewControllerBasedStatusBarAppearance (Boolean - iOS) Specifies whether the status bar appearance is based on the style preferred by the view controller that is currently under the status bar. When this key is not present or its value is set to YES, the view controller determines the status bar style. When the key is set to NO, view controllers (or the app) must each set the status bar style explicitly using the UIApplication object.
UIViewControllerBasedStatusBarAppearance key is the same as View controller-based status bar appearance key.
If you don't add the key,your method should work. try add both methods in these two Viewcontrollers, and add some breakpoint to see they're called or override by mistake.
The code in Swift 3.0 Xcode 8.2 works for me:
override open var preferredStatusBarStyle: UIStatusBarStyle {
return .lightContent
}
override open var prefersStatusBarHidden: Bool {
return true
}
I am hiding my navigation bar when I scroll by calling: self.navigationController?.setNavigationBarHidden(true, animated: true)
The only problem is that the navbar doesnt get hidden all the way.
Whats even stranger is if I push to a new VC and go back and now try to scroll the navigation bar gets hidden all the way which is what I want.
If it matters I am hiding the navigation bar on VC2 then showing it when I exit back to VC 1.
This is what it looks when I try to hide the navbar first time, it doesnt go up all the way/underlying view showing too much.
If I push the to next VC and go back and now try to hide the navigationbar it works
The my view has a constraint of 0 to top layout so its hugging the top
So how can I make my view always be like in the second image when hiding my navigation bar?
Try this code...
Note: This is a simple approach for your problem. If you want more custom look navBar and status bar look .You should read my previous comment...
Set navigation controller property hidesBarsOnSwipe to true
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
navigationController?.hidesBarsOnSwipe = true
}
I understand your question.
The green part in your second image is not a navigation bar, it is a status bar.
You can hide the status bar as below.
You should implement prefersStatusBarHidden on your view controller(s):
In Swift 2:
override func prefersStatusBarHidden() -> Bool {
return true
}
In Swift 3:
override var prefersStatusBarHidden: Bool {
return true
}
For some reason, I want to hide the navigation bar but not the status bar(the signal, time, battery). When I use
self.navigationController?.navigationBarHidden = true
This hides the navigation bar but also hides the status bar. Is there any way to avoid this?
Thanks
Use this code to hide navigation bar:
navigationController?.setNavigationBarHidden(true, animated: true)
And use this code to unhide status bar:
override func prefersStatusBarHidden() -> Bool {
return false
}
And check your plist file if View controller-based status bar appearance is set to NO then change it with YES as shown in below image:
Looking through all the solutions given to similar questions, I have been trying to get the statusBar to show/hide with a tap gesture.
I have set View controller-based status bar appearance = NO in the plist.
I have tried the following code in my DataViewController (page view controller) AND in the RootViewController:
let app = UIApplication.sharedApplication()
app.setStatusBarHidden(true, withAnimation: UIStatusBarAnimation.Fade)
and it doesn't work.
This is embedded in a UITabBarController, would that make a difference?
Also, I was able to get the following to hide the statusBar from the RootViewController:
override func prefersStatusBarHidden() -> Bool {
return true
}
But the DataViewController does not even call this function, and was only able to hide it permanently this way, rather than toggle it on/off.
Any ideas?
I have tried it in code, everything works fine for me. Make sure that the View controller-based status bar appearance is Set to NO. And there is no needs to override prefersStatusBarHidden().
if you using UIPageViewController then you should use this code in the RootViewController
if you have a navigationController it will hide it too
on ViewDidLoad()
self.navigationController?.hidesBarsOnTap = true
and use this method to hide or show the status Bar based on if the navigationBar is hidden or not
override func prefersStatusBarHidden() -> Bool {
if self.navigationController?.navigationBarHidden == true {
return true
}
else
{
return false
}
}