iOS
tab bar
UI customization
Swift
mobile development

Changing tab bar item image and text color iOS

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

Introduction

Changing the image and text color of tab bar items on iOS is mostly a matter of appearance configuration, but the details vary by iOS version and by whether you want global or per-controller styling. The reliable modern approach is to configure UITabBarAppearance and understand the difference between selected and unselected item states.

Basic Tint and Unselected Colors

At the simplest level, UITabBar exposes separate colors for selected and unselected items.

swift
1import UIKit
2
3final class MainTabBarController: UITabBarController {
4    override func viewDidLoad() {
5        super.viewDidLoad()
6
7        tabBar.tintColor = .systemBlue
8        tabBar.unselectedItemTintColor = .systemGray
9    }
10}

tintColor controls the selected item color. unselectedItemTintColor controls the color for unselected icons and titles in the default rendering mode.

This is often enough if you only want a straightforward color change and you are not heavily customizing tab bar appearance.

Use UITabBarAppearance for Modern Customization

On modern iOS versions, UITabBarAppearance gives more explicit control and is the better long-term API.

swift
1import UIKit
2
3final class MainTabBarController: UITabBarController {
4    override func viewDidLoad() {
5        super.viewDidLoad()
6
7        let appearance = UITabBarAppearance()
8        appearance.configureWithOpaqueBackground()
9        appearance.backgroundColor = .white
10
11        appearance.stackedLayoutAppearance.selected.iconColor = .systemBlue
12        appearance.stackedLayoutAppearance.selected.titleTextAttributes = [
13            .foregroundColor: UIColor.systemBlue
14        ]
15
16        appearance.stackedLayoutAppearance.normal.iconColor = .systemGray
17        appearance.stackedLayoutAppearance.normal.titleTextAttributes = [
18            .foregroundColor: UIColor.systemGray
19        ]
20
21        tabBar.standardAppearance = appearance
22        tabBar.scrollEdgeAppearance = appearance
23    }
24}

This is the most reliable approach when you want image and title colors to stay in sync and you also care about background styling.

Make Sure Your Images Render as Templates

Tab bar icon tinting works best when the images render as templates instead of preserving their original asset colors.

swift
1let image = UIImage(systemName: "house")?.withRenderingMode(.alwaysTemplate)
2let selectedImage = UIImage(systemName: "house.fill")?.withRenderingMode(.alwaysTemplate)
3
4viewController.tabBarItem = UITabBarItem(
5    title: "Home",
6    image: image,
7    selectedImage: selectedImage
8)

If you keep original rendering mode, the system cannot reliably recolor the icon using tab bar tint settings.

Customize Through UITabBarItemAppearance

If you want more structured control for different layout styles, access the item appearance object directly.

swift
1let appearance = UITabBarAppearance()
2let itemAppearance = appearance.stackedLayoutAppearance
3
4itemAppearance.normal.iconColor = .lightGray
5itemAppearance.normal.titleTextAttributes = [
6    .foregroundColor: UIColor.lightGray
7]
8
9itemAppearance.selected.iconColor = .systemRed
10itemAppearance.selected.titleTextAttributes = [
11    .foregroundColor: UIColor.systemRed
12]

This is useful when you want selected and normal states to have different typography or when your app uses a more branded color system.

Global Styling Through Appearance Proxies

If your whole application should share one tab bar style, use appearance proxies carefully.

swift
1let appearance = UITabBarAppearance()
2appearance.configureWithDefaultBackground()
3appearance.stackedLayoutAppearance.selected.iconColor = .systemGreen
4appearance.stackedLayoutAppearance.selected.titleTextAttributes = [
5    .foregroundColor: UIColor.systemGreen
6]
7
8UITabBar.appearance().standardAppearance = appearance
9UITabBar.appearance().scrollEdgeAppearance = appearance

Global styling reduces repetition, but it can also make one screen’s special-case styling harder to implement later. Use it only if the visual rule is genuinely app-wide.

Prefer Per-State Configuration Over Ad Hoc Overrides

When debugging tab bar colors, it helps to think in terms of state rather than individual properties. Each item has a normal state and a selected state, and the appearance API lets you define both explicitly. That is more predictable than changing colors in several view controllers and hoping they do not override one another later.

If your app supports different themes, keep the color values in one place and rebuild the UITabBarAppearance object when the theme changes. Centralized appearance construction is easier to test and less error-prone than patching tabBar.tintColor from many screens.

Common Pitfalls

The biggest mistake is using non-template images and then expecting tintColor or appearance settings to recolor them.

Another issue is styling only standardAppearance and forgetting scrollEdgeAppearance, which can create inconsistent visuals on some screens.

People also mix old tint-based code and new appearance-based code without understanding which one currently wins, making the final behavior hard to predict.

Summary

  • Use tintColor and unselectedItemTintColor for simple tab bar color changes.
  • Prefer UITabBarAppearance for modern, explicit customization.
  • Ensure tab bar icons render as templates if they should follow tint colors.
  • Style selected and unselected states separately when you need full control.
  • Keep global appearance rules consistent, especially across standardAppearance and scrollEdgeAppearance.

Related reading
Free course
Beginner
7 lessons
2 hours
Tackling System Design Interview Problems

A short course that equips you with the skills to approach system design interviews methodically.

Start the free course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions