iOS 15 UITabBarController's tabBar background color turns black

IosSwiftUitabbarcontrollerUitabbarIos15

Ios 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: enter image description here

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):

enter image description here

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionZhengqian KuangView Question on Stackoverflow
Solution 1 - Iosanon_nerdView Answer on Stackoverflow
Solution 2 - IosCharlie SeligmanView Answer on Stackoverflow
Solution 3 - IosDaniel StormView Answer on Stackoverflow
Solution 4 - IosMohit KumarView Answer on Stackoverflow
Solution 5 - IoslewisView Answer on Stackoverflow
Solution 6 - IosRafat touqir RafsunView Answer on Stackoverflow
Solution 7 - IosStefoView Answer on Stackoverflow
Solution 8 - IosJay LieskeView Answer on Stackoverflow
Solution 9 - IosChuckZHBView Answer on Stackoverflow
Solution 10 - IosEdward MordrakeView Answer on Stackoverflow
Solution 11 - IosemrazView Answer on Stackoverflow
Solution 12 - IosGlenn PosadasView Answer on Stackoverflow
Solution 13 - IosDmytro YashchenkoView Answer on Stackoverflow
Solution 14 - IosArtorr94View Answer on Stackoverflow
Solution 15 - IosMeetView Answer on Stackoverflow
Solution 16 - IosWasimView Answer on Stackoverflow
Solution 17 - IosRadhe YadavView Answer on Stackoverflow