iOS 15 UITabBarController's tabBar background color turns black
IosSwiftUitabbarcontrollerUitabbarIos15Ios Problem Overview
tabBar.barTintColor
can't be changed in iOS 15 beta 4.
Background. We have an app in App Store and each year before the new iOS major version releases we download the iOS beta and test our app to fix the issues beforehand.
Our problem. This year when testing in iOS 15 beta 4 we found the UITabBarController's tabBar background color turns black and makes the item (both icon and title) hard to read. In our code we had self.tabBar.barTintColor = .white and this line of code doesn't work in iOS 15.
Our attempts. I search online and found a similar, not exactly the same, issue reported, https://developer.apple.com/forums/thread/682420. And I tried standardAppearance
but this is not the solution since with appearance
I can't change tabBar.tintColor
.
Ios Solutions
Solution 1 - Ios
I had the same issue and found the same link that is in your question. I used the same approach for the tab bar.
This is the code i am using and it works perfectly.
if #available(iOS 15.0, *) {
let appearance = UITabBarAppearance()
appearance.configureWithOpaqueBackground()
appearance.backgroundColor = customColor
self.tabController.tabBar.standardAppearance = appearance
self.tabController.tabBar.scrollEdgeAppearance = view.standardAppearance
}
Solution 2 - Ios
Similar to an answer above but with a fix for view not being recognised if you are using custom classes:
if #available(iOS 15.0, *) {
let appearance = UITabBarAppearance()
appearance.configureWithOpaqueBackground()
appearance.backgroundColor = .white
tabBar.standardAppearance = appearance
tabBar.scrollEdgeAppearance = tabBar.standardAppearance
}
Solution 3 - Ios
Create a UITabBarAppearance
like this to maintain the same visual behavior as previous iOS versions:
@available(iOS 15.0, *)
private func updateTabBarAppearance() {
let tabBarAppearance: UITabBarAppearance = UITabBarAppearance()
tabBarAppearance.configureWithOpaqueBackground()
let barTintColor: UIColor = .white
tabBarAppearance.backgroundColor = barTintColor
updateTabBarItemAppearance(appearance: tabBarAppearance.compactInlineLayoutAppearance)
updateTabBarItemAppearance(appearance: tabBarAppearance.inlineLayoutAppearance)
updateTabBarItemAppearance(appearance: tabBarAppearance.stackedLayoutAppearance)
self.tabBar.standardAppearance = tabBarAppearance
self.tabBar.scrollEdgeAppearance = tabBarAppearance
}
@available(iOS 13.0, *)
private func updateTabBarItemAppearance(appearance: UITabBarItemAppearance) {
let tintColor: UIColor = .red
let unselectedItemTintColor: UIColor = .green
appearance.selected.iconColor = tintColor
appearance.normal.iconColor = unselectedItemTintColor
}
Solution 4 - Ios
I tried above answers which are correct. I want to add more properties in those solutions. My requirement was to change background color of tab bar , changing selected image and title color, changing un selected image and title color. I was able to achieve it in iOS 15 using below code.
if #available(iOS 15.0, *){
let appearance = UITabBarAppearance()
appearance.configureWithDefaultBackground()
appearance.backgroundColor = UIColor.appDarkColorLightShade
appearance.compactInlineLayoutAppearance.normal.iconColor = .lightText
appearance.compactInlineLayoutAppearance.normal.titleTextAttributes = [.foregroundColor : UIColor.lightText]
appearance.inlineLayoutAppearance.normal.iconColor = .lightText
appearance.inlineLayoutAppearance.normal.titleTextAttributes = [.foregroundColor : UIColor.lightText]
appearance.stackedLayoutAppearance.normal.iconColor = .lightText
appearance.stackedLayoutAppearance.normal.titleTextAttributes = [.foregroundColor : UIColor.lightText]
self.tabBarController?.tabBar.standardAppearance = appearance
self.tabBarController?.tabBar.scrollEdgeAppearance = self.tabBarController?.tabBar.standardAppearance
self.tabBarController?.tabBar.tintColor = .white
}else{
self.tabBarController?.tabBar.barTintColor = .appDarkColorLightShade
self.tabBarController?.tabBar.unselectedItemTintColor = .lightText
self.tabBarController?.tabBar.tintColor = .white
}
Solution 5 - Ios
iOS 15: We saw this. This is what I changed in our storyboard to make it work:
This slightly altered the appearance in iOS 14, but it was ok for our needs.
Solution 6 - Ios
For me it's simple and you don't need to get access to UINavigationController
instance. Just call it from AppDelegate:didFinishLaunchingWithOptions
if #available(iOS 15.0, *) {
let appearance = UITabBarAppearance()
appearance.configureWithOpaqueBackground()
UITabBar.appearance().standardAppearance = appearance
UITabBar.appearance().scrollEdgeAppearance = appearance
}
Solution 7 - Ios
My tab bar was transparent. And this:tabBar.scrollEdgeAppearance = tabBar.standardAppearance
doesn't do the trick for me.
I had to replace it with tabBar.scrollEdgeAppearance = appearance
. I assume it's the same for navigation bar too.
So the final fix looks like:
if #available(iOS 15.0, *) {
let appearance = UITabBarAppearance()
appearance.configureWithOpaqueBackground()
appearance.backgroundColor = .white //or whatever your color is
tabBar.scrollEdgeAppearance = appearance
tabBar.standardAppearance = appearance
}
Also the Rafat touqir Rafsun's answer above works fine if you want to set the appearance in the appdelegate.
Tested on iOS 15.0.1, Xcode 13.
Solution 8 - Ios
My app has an opaque tab bar below a table view. In iOS 14.x and earlier, it was sufficient to set the barTintColor
on a UIAppearance
proxy, but in iOS 15.0 the tab bar background was black when the table view didn't reach the bottom of the screen.
My solution for iOS 15 is to continue using the UIAppearance
proxy rather than the newer UITabBarAppearance
class. I just needed to set backgroundColor
in addition to barTintColor
. This is backward compatible at least to iOS 11.
let tabBarAppearance = UITabBar.appearance()
tabBarAppearance.isTranslucent = false
tabBarAppearance.barTintColor = barColor
tabBarAppearance.backgroundColor = barColor
Solution 9 - Ios
For Swift, I use code below to keep my app has the same look as before. My tabbar has pink selected color for both icon & title. And with default gray tint color.
To use configureWithDefaultBackground
instead of configureWithOpaqueBackground
because I want a bit transparency of the tabbar.
For now, it is working well, keep looking for the latest changes.
if #available(iOS 15, *) {
let appearance = UITabBarAppearance()
appearance.configureWithDefaultBackground()
appearance.stackedLayoutAppearance.normal.iconColor = .systemGray
appearance.stackedLayoutAppearance.normal.titleTextAttributes = [NSAttributedString.Key.foregroundColor: UIColor.systemGray]
appearance.stackedLayoutAppearance.selected.iconColor = .systemPink
appearance.stackedLayoutAppearance.selected.titleTextAttributes = [NSAttributedString.Key.foregroundColor: UIColor.systemPink]
// appearance.backgroundColor = .systemBackground
self.tabBar.standardAppearance = appearance
self.tabBar.scrollEdgeAppearance = appearance
}
if #available(iOS 13, *) {
let appearance = UITabBarAppearance()
appearance.shadowImage = UIImage()
appearance.shadowColor = .white
appearance.stackedLayoutAppearance.normal.iconColor = .systemGray
appearance.stackedLayoutAppearance.normal.titleTextAttributes = [NSAttributedString.Key.foregroundColor: UIColor.systemGray]
// appearance.stackedLayoutAppearance.normal.badgeBackgroundColor = .yellow
appearance.stackedLayoutAppearance.selected.iconColor = .systemPink
appearance.stackedLayoutAppearance.selected.titleTextAttributes = [NSAttributedString.Key.foregroundColor: UIColor.systemPink]
self.tabBar.standardAppearance = appearance
}
Solution 10 - Ios
Xcode 13.0 - iOS 15.0
My goal was to update the navigation bar tint color dynamically on the view controller change. I set these settings first. Then called this function when needed with UIColor I want to use.
Call:
setNavigationBarAppearance(color: .green)
Extension:
// MARK: Navigation Bar Appearance Function
extension MainViewController {
func setNavigationBarAppearance(color: UIColor) {
if #available(iOS 15.0, *){
let appearance = UINavigationBarAppearance()
appearance.configureWithDefaultBackground()
appearance.backgroundColor = color // The background color.
self.navigationController?.navigationBar.standardAppearance = appearance
self.navigationController?.navigationBar.scrollEdgeAppearance = self.navigationController?.navigationBar.standardAppearance
} else { // Background color support for older versions
self.navigationController?.navigationBar.barTintColor = color
}
}
}
EDIT: Navigation bar tint color won't work on earlier devices while using these settings, sorry for the misinformation. Reverting the settings below makes the tint color works as intended in all versions.
My settings (Tint color works perfectly, on iOS 13.5 and iOS 15):
Solution 11 - Ios
if #available(iOS 15.0, *) {
navigationController?.view.backgroundColor = UIColor.colorName
}
Solution 12 - Ios
Here's my implementation, Objective-C, for both UITabBar
and UINavigationBar
. They're pretty much the same.
Call this in the didFinishLaunchingWithOptions
in your AppDelegate.m
.
- (void)setupAppearance {
if (@available(iOS 15, *)) {
UIColor *color = [UIColor whiteColor]; // #F5F5F5 for white smoke.
UITabBarAppearance *tabBarAppearance = [UITabBarAppearance new];
tabBarAppearance.backgroundColor = color;
[[UITabBar appearance] setStandardAppearance:tabBarAppearance];
[[UITabBar appearance] setScrollEdgeAppearance:tabBarAppearance];
UINavigationBarAppearance *navBarAppearance = [UINavigationBarAppearance new];
navBarAppearance.backgroundColor = color;
[[UINavigationBar appearance] setStandardAppearance:navBarAppearance];
[[UINavigationBar appearance] setScrollEdgeAppearance:navBarAppearance];
}
}
Solution 13 - Ios
After update to XCode 13 & iOS 15 I also faced some Tab Bar issues with bar background color and items text color for different states. The way I fixed it:
if #available(iOS 15, *) {
let tabBarAppearance = UITabBarAppearance()
tabBarAppearance.backgroundColor = backgroundColor
tabBarAppearance.stackedLayoutAppearance.selected.titleTextAttributes = [.foregroundColor: selectedItemTextColor]
tabBarAppearance.stackedLayoutAppearance.normal.titleTextAttributes = [.foregroundColor: unselectedItemTextColor]
tabBar.standardAppearance = tabBarAppearance
tabBar.scrollEdgeAppearance = tabBarAppearance
} else {
UITabBarItem.appearance().setTitleTextAttributes([.foregroundColor: selectedItemTextColor], for: .selected)
UITabBarItem.appearance().setTitleTextAttributes([.foregroundColor: unselectedItemTextColor], for: .normal)
tabBar.barTintColor = backgroundColor
}
Solution 14 - Ios
If you do not want settings up scrollEdgeAppearance, you can override it as standardAppearance, and all your settings will be in both appearance.
if #available(iOS 15.0, *) {
tabBar.scrollEdgeAppearance = tabBar.standardAppearance
}
Solution 15 - Ios
func setupAppearance() {
// Update based on your font requirements
let font = UIFont.systemFont(ofSize: 12, weight: .bold)
let tabBarAppearance = UITabBarAppearance()
let tabBarItemAppearance = UITabBarItemAppearance()
tabBarItemAppearance.normal.titleTextAttributes = [NSAttributedString.Key.font: font, NSAttributedString.Key.foregroundColor: UIColor.gray]
tabBarItemAppearance.selected.titleTextAttributes = [NSAttributedString.Key.font: font, NSAttributedString.Key.foregroundColor: UIColor.black]
/* Note: To reset background and shadow properties to display opaque colors can use - tabBarAppearance.configureWithOpaqueBackground() */
tabBarAppearance.backgroundColor = .white
tabBarAppearance.stackedLayoutAppearance = tabBarItemAppearance
tabBar.standardAppearance = tabBarAppearance
if #available(iOS 15.0, *) {
tabBar.scrollEdgeAppearance = tabBarAppearance
}
}
Solution 16 - Ios
Inside subclass of UITabBarController
if #available(iOS 15.0, *) {
let appearance = UITabBarAppearance()
appearance.configureWithOpaqueBackground()
appearance.backgroundColor = .white
tabBar.standardAppearance = appearance
tabBar.scrollEdgeAppearance = tabBar.standardAppearance
}
Solution 17 - Ios
this is perfect way to fix the tabbar items title color for select and normal items
let tabBarAppearance = UITabBarAppearance()
let tabBarItemAppearance = UITabBarItemAppearance()
tabBarItemAppearance.normal.titleTextAttributes = [NSAttributedString.Key.foregroundColor: UIColor.red]
tabBarItemAppearance.selected.titleTextAttributes = [NSAttributedString.Key.foregroundColor: UIColor.blue]
tabBarAppearance.stackedLayoutAppearance = tabBarItemAppearance
tabBar.standardAppearance = tabBarAppearance
tabBar.scrollEdgeAppearance = tabBarAppearance