How to control tab bar item color in Swift 4?

I would like to have control over the color of a TabBar item based on some event.


I have tried the following:


UITabBarItem.appearance().setTitleTextAttributes([NSAttributedStringKey.foregroundColor: UIColor.red], for:.selected)
UITabBar.appearance().backgroundColor = UIColor(red:1, green:0, blue:0, alpha:1) /
UITabBar.appearance().tintColor = UIColor(red: 1, green: 0, blue: 0, alpha: 1) // New!!


After much experimenting, the only way I have been able to trigger this code is to place them within


func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool
{...}


I have also created a TabBarController.swift file and linked that to the tab bar view controller. Within this Swift file I have used the following function:


func tabBarController(_ tabBarController: UITabBarController, didSelect viewController: UIViewController) {
        print("\nIn  >  MyTabBarViewController  >  tabBarController() ..................................9-9-9-9-9\n\n")
       
        if viewController is Tab1ViewController {
       
            print("Tab One Pressed")
           
        } else if viewController is Tab2ViewController {
       
            UITabBarItem.appearance().setTitleTextAttributes([NSAttributedStringKey.foregroundColor: UIColor.red], for:.selected)
            UITabBar.appearance().backgroundColor = UIColor(red:1, green:0, blue:0, alpha:1) /
            UITabBar.appearane().tintColor = UIColor(red: 1, green: 0, blue: 0, alpha: 1) /
           
            print("Tab Two Perssed")
    }

Pressing either tab bar item does result in the printed text appearing in the console but the code within the if-stmt is ignored.


Any help will be greatly appreciated. Thanks.

Replies

I forgot to note that I set the tab bar controller delegate in the viewDidLoad() method as follows:


override func viewDidLoad() {
        super.viewDidLoad()
       
        print("\nIn  >  MyTabBarViewController  >  viewDidLoad() ..................................9-9\n\n")
       
        self.delegate = (self as UITabBarControllerDelegate)
    }

Thanks!

Is the if statement ignored, or does the log print but tint doesn't change ? That's not the same.

The code is not ignored, but not doing what you expect.


Think you need to use another property:


UITabBarItem.appearance().setTitleTextAttributes([NSForegroundColorAttributeName: UIColor.red], for: .selected) UITabBarItem.appearance().setTitleTextAttributes([NSForegroundColorAttributeName: UIColor.red], for: .normal)


h ttps://stackoverflow.com/questions/26704896/swift-uitabbaritem-colors

Thanks for the feedback. I tried that but was forced to modify your code by an Xcode error suggestion. Result was that your code snippets ended up duplicating what I was originally using:


func tabBarController(_ tabBarController: UITabBarController, didSelect viewController: UIViewController) {
        print("\nIn  >  MyTabBarViewController  >  tabBarController() ..................................9-9-9-9-9\n")
     
        if viewController is Tab1ViewController {
     
            print("\nTab One Pressed\n")
         
        } else if viewController is Tab2ViewController {
     
            /
         
            UITabBarItem.appearance().setTitleTextAttributes([NSAttributedStringKey.foregroundColor: UIColor.red], for: .selected)
         
            UITabBarItem.appearance().setTitleTextAttributes([NSAttributedStringKey.foregroundColor: UIColor.red], for: .normal)
         
        /
            UITabBarItem.appearance().setTitleTextAttributes([NSAttributedStringKey.foregroundColor: UIColor.red], for:.selected)
            UITabBar.appearance().backgroundColor = UIColor(red:1, green:0, blue:0, alpha:1) /
            UITabBar.appearance().tintColor = UIColor(red: 1, green: 0, blue: 0, alpha: 1) /
        */
            print("\nTab Two Pressed\n")
        }
    }

Your code: UITabBarItem.appearance().setTitleTextAttributes([NSForegroundColorAttributeName: UIColor.red], for: .selected)

Xcode forced your code to change to this: UITabBarItem.appearance().setTitleTextAttributes([NSAttributedStringKey.foregroundColor: UIColor.red], for: .selected)


For some reason this code is being ignored and I have no idea why.


Thanks again for your help.

Did you try to call for a redraw after the change, with a needsDisplay ?

Sorry, I overlooked your question:


"Is the if statement ignored, or does the log print but tint doesn't change ? That's not the same.

The code is not ignored, but not doing what you expect."


The if-stmt is not being ignored because the print stmt does print the text string to the console. However, the code within is being ignored. However, as you noted - the code is indeed not doing what I expected it to do.


I do not understand why the code in AppDelegate.swift function noted earlier executes perfectly, but not anywhere else.


Thanks again for your help.

I tried the following code with each segment of the if-stmt as well as the viewDidLoad() method:


self.view.setNeedsDisplay()


This had no affect on the execution of the desired code.


Thanks!

Have you read this note in UIApperance:


Note

iOS applies appearance changes when a view enters a window, it doesn’t change the appearance of a view that’s already in a window. To change the appearance of a view that’s currently in a window, remove the view from the view hierarchy and then put it back.


So, you should change the appearance before the view is inserted.


Note:

I tested in an App, by calling this in the viewController that will segue to the tabBarController.

And it works.

Thanks, Claude31.


I will check this out and report back.

OK, I think I found a workable solution for what I am trying to do. This is still in the testing stage, but it works.


To be clear, I want a specific tab bar item to take on a certain color if some condition is met. So what I did was add the following code to viewWillAppear() as follows: ( the boolean tag controls the behavior of the code ...)


class Tab2ViewController: UIViewController {

    var tabBarTag: Bool = true
   
   
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
       
        if tabBarTag == true {
            self.tabBarController?.tabBar.tintColor = UIColor.red
        } else {
            self.tabBarController?.tabBar.tintColor = UIColor.blue
        }
       
    }

This code will have to be placed within each viewcontroller's viewWillAppear() method, but I think this will work.


I will know more later, but this is code is at the very least, predictable, which was more that I could say for all the code I tried yesterday.


Thanks again for your help.

Grat. Tell if that works, and don't forget to close the thread if so.

Will do!! Thanks.