Before I start I would to apologise if this question is duplicated as I seen plenty of question but I can't find out what I need.
I want to create a global Status, navigation, toolbar bar style and, if possible, the bottom part of the view on iPhones X onwards from my app delegate only so I don't have to set it form each Viewcontroller.
So far I have:
extension UIApplication {
var statusBarView: UIView? {
return value(forKey: "statusBar") as? UIView
}
}
and a function called inside the didFinishLaunchingWithOptions method
private func setupNavigationBarStyle(){
UIApplication.shared.statusBarView!.backgroundColor = UIColor.AppColors.statusBar
UIApplication.shared.statusBarStyle = .lightContent
UINavigationBar.appearance().barTintColor = .brown
UINavigationBar.appearance().tintColor = .green
UINavigationBar.appearance().titleTextAttributes = [NSAttributedString.Key.foregroundColor: UIColor.yellow]
UINavigationBar.appearance().isTranslucent = false
}
I attach a dummy design for my view controller using the storyboard
and the final result is
Despite not being the best design I have 3 questions.
UIApplication.shared.statusBarStyle = .lightContent is deprecated and it shows a warning and I don't want that.
How can I change the color for the bottom for iPhone X onwards (currently in red and and where the Horizontal line is).
Can I change statusBarStyle for another not defined and change the text color in my status bar Purple?
I hope it will help you
UIApplication.shared.statusBarStyle = .lightContent is deprecated and it shows a warning and I don't want that.
Go to Project -> Target, Set Status Bar Style to Light
How can I change the color for the bottom for iPhone X onwards (currently in red and and where the Horizontal line is).
it is not possible to modify the color, and you shouldn’t worry about it, since it’s out of your control and guaranteed to be visible.For Info(https://medium.freecodecamp.org/reverse-engineering-the-iphone-x-home-indicator-color-a4c112f84d34).
Can I change statusBarStyle for another not defined and change the text color in my status bar Purple?
func setStatusBarBackgroundColor(color: UIColor) {
guard let statusBar = UIApplication.shared.value(forKeyPath: "statusBarWindow.statusBar") as? UIView else { return }
statusBar.backgroundColor = color
}
//Use self.setStatusBarBackgroundColor(color: .purple)
Thanks
Related
I faced a weird problem. I wanted to change the colors of my tabBar in just one of my view controllers of my tabBar. How do I achieve this in iOS > 13?
After searching a lot and finding no working solutions, I succeeded by luck.
I found out that you must set an appearance object before I can change them!!
But if you set appearance before the override function endAppearanceTransition() of UITabbar it is working, but not anymore. finally, this way worked:
Set an empty appearance object at viewDidLoad of one of the view Controllers or UITabbarViewcontroller to be executed one time:
override func viewDidLoad() {
super.viewDidLoad()
tabBarController?.tabBar.standardAppearance = UITabBarAppearance()
}
Then you can use updating like this at anytime:
let attrs = [NSAttributedString.Key.foregroundColor: UIColor.green]
tabBarController?.tabBar.backgroundColor = barColor
tabBarController?.tabBar.standardAppearance.stackedLayoutAppearance.selected.iconColor = .green
tabBarController?.tabBar.standardAppearance.stackedLayoutAppearance.normal.iconColor = .green
tabBarController?.tabBar.standardAppearance.stackedLayoutAppearance.normal.titleTextAttributes = attrs
tabBarController?.tabBar.standardAppearance.stackedLayoutAppearance.selected.titleTextAttributes = attrs
I tested against iOS 14.5
We would like to provide ability to change the navigation bar color during runtime.
However, I notice the following code no longer has any effect.
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
navigationController?.navigationBar.backgroundColor = UIColor.red
navigationController?.navigationBar.tintColor = UIColor.red
UINavigationBar.appearance().barTintColor = UIColor.red
}
}
But, if I did it directly in Storyboard, it works just fine.
We would like to have ability to change the various different color during runtime (via user button clicked)
Does anyone has any idea why the above code broken?
Thanks.
p/s I can confirm the navigationController is not nil.
On iOS 13 & above, you have to use new UINavigationBarAppearance api to get the correct color.
public extension UINavigationBar {
func applyPlainAppearanceFix(barTintColor: UIColor, tintColor: UIColor) {
if #available(iOS 13, *) {
let appearance = UINavigationBarAppearance()
appearance.configureWithOpaqueBackground()
appearance.backgroundColor = barTintColor
self.standardAppearance = appearance
self.compactAppearance = appearance
self.scrollEdgeAppearance = appearance
}
self.isTranslucent = false
self.barTintColor = barTintColor
self.backgroundColor = barTintColor
self.tintColor = tintColor
}
}
From the call site it should look like
navigationController?.navigationBar.applyPlainAppearanceFix(barTintColor: .red, tintColor: .white)
Could you try adding this in your AppDelegate and I think it will work, if you didn't want it for all the app then your code is working fine, I've used it and it's working like in the image below:
I am building an app for iOS13. I want to change the text color of status bar according to the color scheme which user can select. It seems the text color of status bar cannot be changed directly, so I try to change the statusBarStyle instead.
First I try:
var myStatusBarStyle = UIStatusBarStyle.default { didSet { setNeedsStatusBarAppearanceUpdate() } }
override var preferredStatusBarStyle : UIStatusBarStyle { return myStatusBarStyle; }
But it did not work.
Then I try:
UIApplication.shared.statusBarStyle = myStatusBarStyle;
It does do the job! But Xcode gives a warnning: " 'statusBarStyle' was deprecated in iOS 13.0: Use the statusBarManager property of the window scene insted."
so, in sceneWillEnterForeground(_ scene: UIScene) I try:
guard let ws = (scene as? UIWindowScene) else { return }
if let t = ws.statusBarManager { print(t.statusBarStyle) }
Unfortunately, t.statusBarStyle is readonly.
Now, how can I do?
ps: I have no Navigation Bar or Tab Bar in the Main.storyboard.
in iOS 13, we are not allowed to do that but there are always escape roots..
I used
self.navigationController?.navigationBar.barStyle = .black
To make status bar black and it works
You can use various options instead of black as you like (.default , .blackTranslucent , .blackOpaque) in place of .black
I'm trying to implement a toggle for dark mode in my app - this would involve toggling the nav bar color to black when the UIViewController is already visible on the screen. I'm aware of how to do this by setting
UINavigationBar.appearance().barTintColor = .black
UINavigationBar.appearance().tintColor = .white
UINavigationBar.appearance().titleTextAttributes = [NSAttributedString.Key.foregroundColor: UIColor.white]
UINavigationBar.appearance().isTranslucent = false
in the AppDelegate, however, this won't work in this case as it needs to be done dynamically.
I've also tried navigationController?.navigationBar.barTintColor = UIColor.white but this doesn't work either.
UPDATE:
I think a lot of the responses were confused with the purpose of this question - this is NOT at all related to the iOS13 Dark Mode which was just released - it is an INDEPENDENT dark mode feature I want to add to my app (similar to other apps like Messenger etc which had dark mode available IN-APP before iOS 13 was released). What I need to do is dynamically update the color of the UINavigationBar AFTER it has been already displayed on the screen, the same way I can change the background color of a view by doing view.backgroundColor = .white and this will update the color in real-time on screen.
Achieved this by making the nav bar translucent (in AppDelegate):
let barAppearance = UINavigationBar.appearance()
barAppearance.titleTextAttributes = [NSAttributedString.Key.foregroundColor: appRed]
barAppearance.setBackgroundImage(UIImage(), for: UIBarMetrics.default)
barAppearance.shadowImage = UIImage()
barAppearance.isTranslucent = true
Next I create a view and place it behind the nav bar as follows (using SnapKit):
let coverView = UIView()
cover.snp.makeConstraints {
make in
make.left.right.top.equalTo(self)
make.bottom.equalTo(self.snp.top).offset(universalNumber(num: parent!.topbarHeight))
}
where the parent is my UIViewController and topBarHeight is:
extension UIViewController {
/**
* Height of status bar + navigation bar (if navigation bar exist)
*/
var topbarHeight: CGFloat {
return UIApplication.shared.statusBarFrame.size.height +
(self.navigationController?.navigationBar.frame.height ?? 0.0)
}
}
Finally, to update the color I set
coverView.backgroundColor = universalWhite()
where
func universalWhite() -> UIColor {
let defaults = UserDefaults.standard
let darkMode = defaults.bool(forKey: "darkMode")
if darkMode {
return .black
} else {
return .white
}
}
You may want to check out the traits provided with the UIViewController to determine the current Interface style, instead of a manual check for versions running iOS 13+. Using this method, you can define colors in your Assets folder for both appearances.
For below iOS 13, you can use something similar to what #byaruah stated, but that is not a global effect. You should also consider using the UINavigationBar.appearance() functionality for a global approach.
How to change the background color and text color of done button? Is there a way that I can change the navigationbar color and navigation bar title color and bottom bar color also? Attached screenshot for reference:
I solved it. Here is the code working for me perfectly:
func documentInteractionControllerViewControllerForPreview(_ controller: UIDocumentInteractionController) -> UIViewController {
UINavigationBar.appearance().barTintColor = Colors.redColor()
UINavigationBar.appearance().tintColor = UIColor.white
UINavigationBar.appearance().titleTextAttributes = [NSForegroundColorAttributeName : UIColor.white, NSFontAttributeName: UIFont.systemFont(ofSize: 14, weight: UIFontWeightBold)]
return self
}
It's a little hacky as its relying on the fact that QLPreviewController is the class implementing the UIDocumentInteractionController but something like this is the least intrusive solution. Do it before you display the UIDocumentInteractionController
import QuickLook
UIBarButtonItem.appearance(whenContainedInInstancesOf [QLPreviewController.self]).tintColor = UIColor.black
I have a idear to change the bar color:
let allNavigationBar = UINavigationBar.appearance()
allNavigationBar.barTintColor = UIColor.red // change the bar background color
allNavigationBar.tintColor = UIColor.black // change the Done button's tintColor
let alloolbar = UIToolbar.appearance()
allToolbar.barTintColor = UIColor.red // dones't work, try backgroundImage
allToolbar.backgroundColor = UIColor.blue // dones't work
allToolbar.tintColor = UIColor.brown // change the toolbar's item tint color
but this method has a great effect,all your UINavigationBarand UIToolBar will make that change.
Hope anyone else can give a better solusion.
You can change the tint color of the window temporally.
func presentDocument() {
//present the controller here
self.appDelegate.window.tintColor = UIColor.red
}
Then change it back later:
func documentInteractionControllerDidEndPreview(documentInteractionController) { //replace parameter with your uidocumentviewinteractioncontroller
self.appDelegate.window.tintColor = UIColor.white
}
#Dee. I guess you have asked this part in one of your other question. In that case you were not able to show that preview controller. In that question suggested answer is to return "self" from that delegate method. If you implement that correctly then your preview will use same navigation bar colour as its parent controller is using. I mean if you have opened UIDocumentInteractionController directly from some ViewController then UIDocumentInteractionController will use its parent viewController's navigation bar colour. This may help you to change Done button colour
Try this : (You need to implement UIDocumentInteractionControllerDelegate)
func documentInteractionControllerViewControllerForPreview(_ controller: UIDocumentInteractionController) -> UIViewController {
return self.navigationController ?? self
}
let QLNavAppearance = UINavigationBar.appearance(whenContainedInInstancesOf: [QLPreviewController.self])
QLNavAppearance.tintColor = UIColor.red // some
QLNavAppearance.barTintColor = UIColor.red // some
QLNavAppearance.backgroundColor = UIColor.red // some