Change Color to Dark Mode Tab Bar

Jerry PM
3 min readOct 8, 2024

--

My Bug, My Story

Photo by Luca Bravo on Unsplash

I recently worked on fixing a bug related to the UITabBarController, which involved four Tab Bar Menu Items: Home, Stock, Fund, and Portfolio. The bug, reported in a Jira ticket, was titled “wrong icon color at navbar in dark mode.” Let me walk you through the issue in detail.

Issue Details:

  • The assets were set up with both Any and Dark variations, meaning there are two sets of assets to support light and dark modes.
  • The problem is that while the tab bar appears correct in light mode, the icons do not update correctly in dark mode.

Try fixing it using ChatGPT

I failed using the logic from ChatGPT, and it provided the following code:

override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
super.traitCollectionDidChange(previousTraitCollection)

if traitCollection.userInterfaceStyle == .dark {
tabBarController?.tabBar.barTintColor = UIColor.black
tabBarController?.tabBar.tintColor = UIColor.white // Active item color
tabBarController?.tabBar.unselectedItemTintColor = UIColor.gray // Inactive item color
} else {
tabBarController?.tabBar.barTintColor = UIColor.white
tabBarController?.tabBar.tintColor = UIColor.blue // Active item color
tabBarController?.tabBar.unselectedItemTintColor = UIColor.lightGray // Inactive item color
}
}

Then, I tried my own approach after researching and debugging. Here are my two attempts:

First Attempt: Using NotificationCenter

I initially tried solving this by implementing NotificationCenter to listen for theme changes. This approach allowed the app to respond to system-wide theme switches from the settings. When the theme was switched to dark mode, each tab (Home, Stock, Fund, and Portfolio) would be updated accordingly.

Upon testing, this solution worked perfectly for the Home and Stock tabs, but the Fund and Portfolio tabs did not switch to dark mode as expected. This inconsistency was puzzling and required further investigation.

Second Attempt: Changing Image Asset Render to Original

For my second approach, I adjusted the image asset rendering settings. I went to the Assets folder, navigated to Tabbar-icons, and changed the “Render As” setting in the inspector from Default to Original Image.

This adjustment resolved most of the issues and allowed the icons to appear correctly in dark mode. However, a new problem arose: the selectedImage did not change its color when switching to dark mode. The unselected images worked fine, but the selected image remained stuck in its light mode color.

Update

Finally, I found the solution to fix the selectedImage issue in dark mode. When the theme color is changed to dark or light in the settings, traitCollectionDidChange will directly update the tab bar, and resetup the tabbar using this code below

This the solution I Found

override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
super.traitCollectionDidChange(previousTraitCollection)

// Pastikan ada perubahan mode (light/dark)
if traitCollection.hasDifferentColorAppearance(comparedTo: previousTraitCollection) {
updateTabBarImages()
}
}

func updateTabBarImages() {
if let tabBarItems = tabBar.items {
// Watchlist
tabBarItems[0].image = UIImage(named: "home_unselected", in: Bundle.main, compatibleWith: traitCollection)?.withRenderingMode(.alwaysOriginal)
tabBarItems[0].selectedImage = UIImage(named: "home_selected", in: Bundle.main, compatibleWith: traitCollection)?.withRenderingMode(.alwaysOriginal)

// Stock
tabBarItems[1].image = UIImage(named: "stock_unselected", in: Bundle.main, compatibleWith: traitCollection)?.withRenderingMode(.alwaysOriginal)
tabBarItems[1].selectedImage = UIImage(named: "stock_selected", in: Bundle.main, compatibleWith: traitCollection)?.withRenderingMode(.alwaysOriginal)

// Mutual
tabBarItems[2].image = UIImage(named: "fund_unselected", in: Bundle.main, compatibleWith: traitCollection)?.withRenderingMode(.alwaysOriginal)
tabBarItems[2].selectedImage = UIImage(named: "fund_selected", in: Bundle.main, compatibleWith: traitCollection)?.withRenderingMode(.alwaysOriginal)

// Portfolio
tabBarItems[3].image = UIImage(named: "portfolio_unselected", in: Bundle.main, compatibleWith: traitCollection)?.withRenderingMode(.alwaysOriginal)
tabBarItems[3].selectedImage = UIImage(named: "portfolio_selected", in: Bundle.main, compatibleWith: traitCollection)?.withRenderingMode(.alwaysOriginal)
}
}

--

--