iOS 13 UIBarButtonItem color in dark mode - ios

My UIBarButtonItem image doesn't change its color when switching between dark and light mode.
I set the color programmatically and expected it to change between black and white when switching the mode.
At least it works with the tintColor of my NavigationBar.
I set:
myBarButton.tintColor = UIColor.white
and the image of the button stays white in dark AND in light mode.
On the other hand, the following is black in light mode and white in dark mode:
navigationBar.tintColor = UIColor.white
Why does it behave differently and how can I add this functionality to my UIBarButtonItem?

UIColor.white is not a dynamic color. It will be white regardless of the appearance setting. If you want a color that is different depending on the appearance, you need to take one of the new dynamic system colors (e.g., UIColor.systemBackground would be white in light and black in dark mode), or create a color asset with different color values for light and dark appearance in an asset catalog.
Here is more on the new system colors: https://developer.apple.com/design/human-interface-guidelines/ios/visual-design/color#dynamic-system-colors

Using iOS 13's new appearance API:
https://developer.apple.com/documentation/uikit/uinavigationbarappearance
Example:
let navStyle = UINavigationBarAppearance()
let buttonStyle = UIBarButtonItemAppearance()
// Change properties of buttonStyle here with dynamic colours such as UIColor.label.
style.buttonAppearance = buttonStyle
style.doneButtonAppearance = ...
style.backButtonAppearance = ...
navigationController?.navigationBar.standardAppearance = navStyle
navigationController?.navigationBar.scrollEdgeAppearance = ...
navigationController?.navigationBar.compactAppearance = ...

Related

navigation bar style change while iphone theme is in dark mode

Hello I am creating app with Swift i have just started creating app and take one View Controller and embed in navigation controller and for remove navigation bar border i used below code
self.navigationController?.navigationBar.setBackgroundImage(UIImage(), for:.default)
self.navigationController?.navigationBar.shadowImage = UIImage()
self.navigationController?.navigationBar.layoutIfNeeded()
and for dealing with Dark Theme i have added one more line as below
i am adding Screen Shot Of Light Mode And Dark Mode for better explanation
overrideUserInterfaceStyle = .light
but when iphone is in darkmode Navigation Bar Style changed to light is there any solution to handle navigation bar style while dark mode is enabled
This dark mode Screen Shot
This Is Light Mode Screen Shot
Kindly tell me if anyone have any solution for this
Use UINavigationBarAppearance() to customize UINavigationBar in iOS13 (where dark mode feature appeared):
if #available(iOS 13.0, *) {
let appearance = UINavigationBarAppearance()
appearance.backgroundColor = UIColor.colorYouNeed
self.navigationController?.navigationBar.standardAppearance = appearance
}

UINavigationBar appearance + iOS 13 Dark Mode - How to set app wide color?

In iOS 12 and before I used [[UINavigationBar appearance] setBackgroundColor...] to set a app wide background color for all NavBars.
In iOS 13 I would like to do the same while supporting Dark Mode. In the apps Asset Catalog I defined a named Color NavBarBackground and specified both a Any appearance and Dark appearance color.
If the Dark Mode is disabled the correct Any color is used. However when Dark Mode is enabled the specified Dark color is ignored and all NavBar appear in plain black...
However, if I set the background color of a NavBar manually in IB to NavBarBackground this one NavBar shows the correct color both in Normal and in Dark Mode.
So, how to use [UINavigationBar appearance] together with Dark Mode and named colors?
You can use iOS 13's new appearance API:
https://developer.apple.com/documentation/uikit/uinavigationbarappearance
Example:
let style = UINavigationBarAppearance()
style.backgroundColor = .red
style.barTintColor = UIColor(named: "my_colour")!
navigationController?.navigationBar.standardAppearance = style
navigationController?.navigationBar.scrollEdgeAppearance = ...
navigationController?.navigationBar.compactAppearance = ...

iOS programmatically change all default colours

This code in applicationDidFinishLaunchingWithOptions()
window?.tintColor = .red
window?.backgroundColor = .green
change the default views tint color, not the background color, of my whole application, which is a double view with table view.
The default text color is a black "Color Dark Text" in label texts, and a black "Color default" in text fields.
Is there a way to programmatically change all the defaults color, foreground and background?
Yes, you can do it via appearance. E.g. to change backround color of every view:
UIView.appearance().backgroundColor = .green
Note: If you change background of some view, appearance will not apply.

Change statusBar background color while using large title for navigation bar on iOS 11

I'm trying to use the new navigationBar's large title feature on iOS 11.
However, after I added the following line:
self.navigationController?.navigationBar.prefersLargeTitles = true
I found that the navigationBar background color changed to black.
So I set background color again manually:
self.navigationController?.setBackgroundColor(UIColor(hexString: 0xFF7E79))
However, I found that the statusBar background color didn't change:
After I set up the background color of statusBar through this code:
guard let statusBar = UIApplication.shared.value(forKeyPath: "statusBarWindow.statusBar") as? UIView else { return
statusBar.backgroundColor = UIColor(hexString: 0xFF7E79)
It gives me an ugly 1px black line like this between the statusBar and the navigationBar:
So what is the correct way to set the background color of navigationBar?
The correct way to set the background color of the UINavigationBar is to use the barTintColor property.
self.navigationController?.navigationBar.barTintColor = .red
You may notice that the color you set can be a little faded. As noted in the documentation:
This color is made translucent by default unless you set the isTranslucent property to false.
See the barTintColor reference on developer.apple.com

UISegmentedContol: reverse tintColor and backgroundColor

I have UISegmentedControl that I add a few white images on transparent background to.
for (index,element) in ELEMENTS.enumerate() {
segmentedControl.insertSegmentWithImage(element.logo, atIndex: index, animated: false)
}
Segments not selected now have the background color set to segmentedControl.backgroundColor, and the image is colored with segmentedControl.tintColor. The selected segment is reversed, with the background set to .tintColor, and the image colored with the .backgroundColor.
This works fine, but I would like it to be the other way around: That the selected segment has a image colored with .tintColor, and background colored .backgroundColor.
I know I can achieve this by just switching the colors in code, but I'm using
let sharedApplication = UIApplication.sharedApplication()
sharedApplication.delegate?.window??.tintColor = newColor
in the app to change the tintColor of all the views in the app, so it would be nice if this would result in the color being changed the way I want it in my segmented control.
Any ideas?
You use UIApplication.sharedApplication().delegate?.window??.tintColor to set global tint color that is used by all controls of your application.
You can use UISegmentedControl.appearance().tintColor to set custom tint color for all segmented controls in your application.
And you can use UISegmentedControl.tintColor to set custom tint color for specific segmented control.
To switch background and tint colors for all segmented controls in your application:
UISegmentedControl.appearance().tintColor = backgroundColor
UISegmentedControl.appearance().backgroundColor = tintColor

Resources