I want to show the status bar on portrait mode only, when I rotate the screen the status bar hides as intended but if I push / show a new View Controller the status bar appears again.
I've tried the following without success:
Setting View controller-based status bar appearance to NO in the info.plist file
Using setNeedsStatusBarAppearanceUpdate() on self and on NavigationController
Setting prefersStatusBarHidden: Bool to true
Also tried UIApplication.shared.setStatusBarHidden(true, with: UIStatusBarAnimation.none)
Also extending NavigationController. seen here
Any help will be appreciated. Thanks.
Try Following Code
override var prefersStatusBarHidden: Bool {
if UIDevice.current.orientation.isPortrait{
return false
}
return true
}
Related
Adding
application.statusBarStyle = .lightContent
to my AppDelegate's didFinishLaunchingWithOptions method nor adding
override var preferredStatusBarStyle: UIStatusBarStyle {
return UIStatusBarStyle.lightContent
}
to the VC no longer works on iOS12/Xcode10
Any ideas?
This has nothing to do with iOS 12. You just have the rules wrong.
In a navigation controller situation, the color of the status bar is not determined by the view controller’s preferredStatusBarStyle.
It is determined, amazingly, by the navigation bar’s barStyle. To get light status bar text, say (in your view controller):
self.navigationController?.navigationBar.barStyle = .black
Hard to believe, but true. I got this info directly from Apple, years ago.
You can also perform this setting in the storyboard.
Example! Navigation bar's bar style is .default:
Navigation bar's bar style is .black:
NOTE for iOS 13 This still works in iOS 13 as long as you don't use large titles or UIBarAppearance. But basically you are supposed to stop doing this and let the status bar color be automatic with respect to the user's choice of light or dark mode.
If you choose a same status bar color for each View Controller:
<key>UIViewControllerBasedStatusBarAppearance</key>
<false/>
Ad this to your Info.plist and set status bar color from Project -> Targets -> Status Bar Style by desired color.
On the other hand, in your case, you have a navigation controller which is embedded in a view controller. Therefore, you want to different status bar color for each page.
<key>UIViewControllerBasedStatusBarAppearance</key>
<true/>
Ad this to your Info.plist. Then, create a custom class for your NavigationController. After that you can implement the method:
class LightContentNavigationController: UINavigationController {
override var preferredStatusBarStyle: UIStatusBarStyle {
return .lightContent
}
}
Thats it! Please, inform me whether this was useful!
If Matt's answer isn't working for you, try adding this line of code before you present your viewController.
viewController.modalPresentationCapturesStatusBarAppearance = true
I encountered a bug where setting modalPresentationStyle to overFullScreen does not give the status bar control to the presented view controller or navigation controller.
I was using navigation controller for each tab of UITabBarController. Subclassing UINavigationController and overriding childForStatusBarStyle fixed the issue for me.
class MyNavigationController: UINavigationController {
open override var childForStatusBarStyle: UIViewController? {
return topViewController?.childForStatusBarStyle ?? topViewController
}
}
If you have a modal UIViewController the situation becomes very tricky.
Short answer:
Present modal using UIModalPresentationStyle.fullScreen
override preferredStatusBarStyle (in your modal vc)
call setNeedsStatusBarAppearanceUpdate() in viewWillAppear (in your modal vc)
If you don't want to use UIModalPresentationStyle.fullScreen you have to set modalPresentationCapturesStatusBarAppearance
According to apple doc:
When you present a view controller by calling the
present(_:animated:completion:) method, status bar appearance
control is transferred from the presenting to the presented view
controller only if the presented controller's modalPresentationStyle
value is UIModalPresentationStyle.fullScreen. By setting this property
to true, you specify the presented view controller controls status bar
appearance, even though presented non-fullscreen.
The system ignores this property’s value for a view controller
presented fullscreen.
You can set
vc.modalPresentationCapturesStatusBarAppearance = true
to make the customization works.
Customizing UINavigationController can fix the issue
class ChangeableStatusBarNavigationController: UINavigationController {
override var preferredStatusBarStyle: UIStatusBarStyle {
return topViewController?.preferredStatusBarStyle ?? .default
}
}
Ref: https://serialcoder.dev/text-tutorials/ios-tutorials/change-status-bar-style-in-navigation-controller-based-apps/
My application is having defaultstatus bar style for pre-login screens.
- After login, app uses lightContent style for status bar throughout the app.
All was working fine till iOS 12. It started creating issue with iOS 13 (only when Dark Mode is enabled) .
Here are things which i have already tried, and still not getting things work fine.
I did set UIUserInterfaceStyle to Light
I did set UIViewControllerBasedStatusBarAppearance to YES
Then I tried below code in individual view controller
override var preferredStatusBarStyle: UIStatusBarStyle { return .lightContent }
Also added this line in viewDidLoad() of a class file.
setNeedsStatusBarAppearanceUpdate()
But still, I am not getting rid of this status bar related thing. I just simply need my status bar to be dark in screens before login, and once user logged in, it should the light.
Whole application should have identical UI for both dark and light modes. (as it is for OS below iOS 13) Which is working fine right now, but only status bar is changing colour.
Note: Everything is working fine when Dark Mode is disabled. This creating issues only when Dark Mode is enabled.
For my understanding, I created a new project in Xcode and added 3 screens with different status bar appearance.
A Working case
VC1 - Default Style
VC2 - Default Style
VC3 - LightContent Style
A Working case
VC1 - LightContent Style
VC2 - LightContent Style
VC3 - Default Style
Not Working (Failure) case
VC1 - Default Style
VC2 - LightContent Style
VC3 - Default Style
What I assume is - if you use either of style in your application, it works fine regardless of Dark or Light mode of device. But if you combine Default and LightContent both for status bar appearance in your app, then it is not working as expected while dark mode is enabled.
Can any one please help me with this behaviour of Status Bar Style?
Here are my three view controller files. It simply pushes one controller to other one. It is files for the demo project which I have mentioned above. Which has the failure case.
When Dark Mode is OFF: I always get default status bar style even when I override status bar style in VC2.
When Dark Mode is OFF: I always get lightContent status bar style even when I override status bar style in VC1 & VC3.
Here is my info.plist file
In your case, the navigation controller is responsible for maintaining the status bar style. Therefore, you need to subclass your navigation controller and override its preferredStatusBarStyle.
If you don't want to support dark mode in your app (and it seems like you want fixed light and default colour schemes) then you can opt out of it altogether in your Info.plist by setting
UIUserInterfaceStyle to either light or dark or on each individual viewcontroller you can override var overrideUserInterfaceStyle: UIUserInterfaceStyle { get { .light }
set { //you can leave this empty } }
Edit:
To only change the statusbar appearance without doing anything with darkMode you opt out of dark mode in the Info.plist then add UIUserInterfaceStyle with value YES and in each viewController you want different statusbar style you need to override the preferred statusbar appearance property like so:
override var preferredStatusBarStyle: UIStatusBarStyle {
.lightContent
}
}
and lastly you call setNeedsStatusBarAppearanceUpdate() in viewDidLoad()
Edit2:
if inside a navigation controller you need to set the above inside a custom navi controller class like this:
import UIKit
class Navi: UINavigationController {
public var requiredStatusBarStyle: UIStatusBarStyle = .lightContent {
didSet {
setNeedsStatusBarAppearanceUpdate()
}
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
override var preferredStatusBarStyle: UIStatusBarStyle {
requiredStatusBarStyle
}
}
then in each VC you can set at viewDidAppear the property:
if let navi = navigationController as? Navi {
navi.requiredStatusBarStyle = .darkContent
}
if you don't want a harsh jump between light/dark you can wrap a uiview animation around setneedsstatusbarupdate
public var requiredStatusBarStyle: UIStatusBarStyle = .lightContent {
didSet {
UIView.animate(withDuration: 0.5) {
self.setNeedsStatusBarAppearanceUpdate()
}
}
}
Please try once using this
controller.navigationController?.navigationBar.isTranslucent = false
because in my case it's worked.
You can set default status bar style in General of you project settings.
I'm using UITab bar. In my UITabbar have 4 items and each of tabbar have navigation controller.
i want to put gradient color in the status background of view controller in 1-3 items but in view controller 4 i want it to have a status clear background.
my problem is when i go to tab 1-3 and then go to tab 4 the status background color will change according to the of tab 1-3. But I want the status background color of tab 4 is transparent.
the code that I use to change color of status background in tab 1-3
if let status = UIApplication.shared.value(forKey: "statusBar") as? UIView {
status.setGradientBackground(colorOne: Colors.carmine, colorTwo: Colors.cherryRed, colorThree: Colors.cherryRedTwo)
}
I have tried to hide status bar in Tab 4 by this method
1.change View controller-based status bar appearance to YES
2.put
setNeedsStatusBarAppearanceUpdate()
in viewdidload
3.put
override var prefersStatusBarHidden: Bool {
return true
}
in viewdidappear but still not work background of status bar is not hidding and the status background color still change according to the of tab 1-3.
it have one method that work by using this code
UIApplication.shared.isStatusBarHidden = true
and put it in every view controller
but it have warning like this
Setter for 'isStatusBarHidden' was deprecated in iOS 9.0: Use -[UIViewController prefersStatusBarHidden]
I want to know the correct way to change color of the status bar in UITab Thank you.
Ok, if I understand what you want correctly, you want to make your tab 4 to have a clear status bar, here's what you can try if your main view in tab 4, has subviews. Once you change your main view color, the status bar color changes also :
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(true)
if let lastTab = tabBarController?.children[3] {
lastTab.view.backgroundColor = UIColor.white // status bar will be clear
}
}
How can I had the status bar whenever the view is scrolling with:
self.navigationController?.hidesBarsOnSwipe = true
or if not hide the status bar, how can I keep my status bar from overlaying my view?
ty awesome stackoverflow community
A Swift 3 elegant solution:
open override var prefersStatusBarHidden: Bool {
return navigationController?.isNavigationBarHidden ?? false
}
Sorry if this answer is a little late, but here is one way to do it.
Use the prefersStatusBarHidden() method within your view controller.
override func prefersStatusBarHidden() -> Bool {
if self.navigationController?.navigationBarHidden == true {
return true
} else {
return false
}
}
Basically says that when the Nav bar is hidden, then the status bar is too and vice versa.
I've try to modify status bar color text but no one answer from this thread doesn't work.
Any especially for XCode 6?
I've tried insert:
override func preferredStatusBarStyle() -> UIStatusBarStyle {
return UIStatusBarStyle.LightContent
}
to UIViewController
also
UIApplication.sharedApplication().setStatusBarStyle(UIStatusBarStyle.LightContent, animated: true)
to AppDelegate.swift
And I've tried change it in info.plist
But it doesn't affect it. How change status bar color text to white?
In your Info.plist you need to define View controller-based status bar appearance to any value.
If you define it YES then you should override preferredStatusBarStyle function in each view controller.
If you define it NO then you can set style in AppDelegate using
UIApplication.sharedApplication().statusBarStyle = .LightContent
Just set " View controller-based status bar appearance == NO " in to your plist and put a single line in your appdelegate class in didfinshLaunching method.
UIApplication.sharedApplication().statusBarStyle = .LightContent
Swift 3.0
Just set View controller-based status bar appearance == NO in to your *.plist and put below code in your appdelegate class in didFinishLaunchingWithOptions method before return.
let statusBar: UIView = UIApplication.shared.value(forKey: "statusBar") as! UIView
if statusBar.responds(to:#selector(setter: UIView.backgroundColor)) {
statusBar.backgroundColor = UIColor.red
}
UIApplication.shared.statusBarStyle = .lightContent
You can change backgroundColor and statusBarStyle as per your requirement.
Be sure to set the View controller-based status bar appearance in your info.plist file to Yes.
Furthermore, if you are in a UINavigationController, you cannot simply set the style in ViewControllers in it. Subclass the UINavigationController and add this to it:
override func preferredStatusBarStyle() -> UIStatusBarStyle {
if let vc = self.viewControllers?.last as? UIViewController {
return vc.preferredStatusBarStyle()
}
return super.preferredStatusBarStyle()
}
Now you can set the bar style in the UIViewController subclass and the UINavigationController will listen to it :).
Keenle is right on, from iOS7 onward, you have to opt out of viewController-based status bar styles before you can set it app-wide.
doc:https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIApplication_Class/index.html#//apple_ref/occ/instm/UIApplication/setStatusBarStyle:animated:
"To opt out of the view controller-based status bar appearance behavior, you must add the UIViewControllerBasedStatusBarAppearance key with a value of NO to your app’s Info.plist file, but doing so is not recommended."