Unselected UITabBar color?
IosUitabbarcontrollerUitabbarUitabbaritemIos Problem Overview
I have an UITabBar with 5 items. I want to change the unselected color of all items. The items aren't declared in the UIViewController classes (i built them and linked the views in the Storyboard).
Is there an code like this : [[UITabBar appearance] set***UN***SelectedImageTintColor:[UIColor whiteColor]];
?
Ios Solutions
Solution 1 - Ios
In iOS 10 and higher, there are 3 possible easy solutions:
A. Instance from code (Swift):
self.tabBar.unselectedItemTintColor = unselectedcolor
B. Instance from IB:
Add a Key Path: unselectedItemTintColor
of type: Color
C. Global appearance (Swift):
UITabBar.appearance().unselectedItemTintColor = unselectedcolor
Solution 2 - Ios
This will not work under iOS 7 as far as I can say. In particular, tintColor of the tab bar will define the color of the selected tab, not of the unselected ones. If you want to change the default in iOS 7, it seems that you have to actually use different icons (in the color you like to have for unselected tabs) and set the color of the text.
This example should tint selected tabs to red and render others in green. Run this code in your TabBarController:
// set color of selected icons and text to red
self.tabBar.tintColor = [UIColor redColor];
[[UITabBarItem appearance] setTitleTextAttributes:[NSDictionary dictionaryWithObjectsAndKeys: [UIColor redColor], NSForegroundColorAttributeName, nil] forState:UIControlStateSelected];
// set color of unselected text to green
[[UITabBarItem appearance] setTitleTextAttributes:[NSDictionary dictionaryWithObjectsAndKeys:[UIColor greenColor], NSForegroundColorAttributeName, nil]
forState:UIControlStateNormal];
// set selected and unselected icons
UITabBarItem *item0 = [self.tabBar.items objectAtIndex:0];
// this way, the icon gets rendered as it is (thus, it needs to be green in this example)
item0.image = [[UIImage imageNamed:@"unselected-icon.png"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
// this icon is used for selected tab and it will get tinted as defined in self.tabBar.tintColor
item0.selectedImage = [UIImage imageNamed:@"selected-icon.png"];
If you set the icon in the story board only, you can control the color of the selected tab only (tintColor). All other icons and corresponding text will be drawn in gray.
Maybe someone knows an easier way to adopt the colors under iOS 7?
Solution 3 - Ios
Extending @Sven Tiffe’s answer for iOS 7, you can get your code to automatically tint the unselected UITabBar images added in the storyboard. The following approach will save you having to create two sets of icon images (i.e. selected vs unselected) and having to programatically load them in. Add the category method imageWithColor: (see - https://stackoverflow.com/questions/19274789/change-image-tintcolor-in-ios7) to your project then put the following in your custom UITabBarController viewDidLoad method:
// set the selected colors
[self.tabBar setTintColor:[UIColor whiteColor]];
[[UITabBarItem appearance] setTitleTextAttributes:[NSDictionary dictionaryWithObjectsAndKeys: [UIColor whiteColor], NSForegroundColorAttributeName, nil] forState:UIControlStateSelected];
UIColor * unselectedColor = [UIColor colorWithRed:184/255.0f green:224/255.0f blue:242/255.0f alpha:1.0f];
// set color of unselected text
[[UITabBarItem appearance] setTitleTextAttributes:[NSDictionary dictionaryWithObjectsAndKeys:unselectedColor, NSForegroundColorAttributeName, nil]
forState:UIControlStateNormal];
// generate a tinted unselected image based on image passed via the storyboard
for(UITabBarItem *item in self.tabBar.items) {
// use the UIImage category code for the imageWithColor: method
item.image = [[item.selectedImage imageWithColor:unselectedColor] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
}
Create a Category called UIImage+Overlay and on UIImage+Overlay.m (extracted from this answer ) :
@implementation UIImage(Overlay)
- (UIImage *)imageWithColor:(UIColor *)color1
{
UIGraphicsBeginImageContextWithOptions(self.size, NO, self.scale);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextTranslateCTM(context, 0, self.size.height);
CGContextScaleCTM(context, 1.0, -1.0);
CGContextSetBlendMode(context, kCGBlendModeNormal);
CGRect rect = CGRectMake(0, 0, self.size.width, self.size.height);
CGContextClipToMask(context, rect, self.CGImage);
[color1 setFill];
CGContextFillRect(context, rect);
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}
@end
Solution 4 - Ios
SO says i cannot delete the accepted answer (i tried), but obviously, there are a lot of upvotes for comments that this doesn't work for iOS 7.
See the other answer below with many more upvotes, or the link in @Liam's comment to this answer.
for iOS 6 only
It should be as simple as this:
[[UITabBar appearance] setTintColor:[UIColor grayColor]]; // for unselected items that are gray
[[UITabBar appearance] setSelectedImageTintColor:[UIColor greenColor]]; // for selected items that are green
Solution 5 - Ios
Swift version in iOS 10 and higher -
UITabBar.appearance().tintColor = UIColor.gray
UITabBar.appearance().unselectedItemTintColor = UIColor.gray
Solution 6 - Ios
Translating user3719695's answer to Swift, which now uses extensions:
UIImage+Overlay.swift
extension UIImage {
func imageWithColor(color1: UIColor) -> UIImage {
UIGraphicsBeginImageContextWithOptions(self.size, false, self.scale)
color1.setFill()
let context = UIGraphicsGetCurrentContext()
CGContextTranslateCTM(context, 0, self.size.height)
CGContextScaleCTM(context, 1.0, -1.0);
CGContextSetBlendMode(context, CGBlendMode.Normal)
let rect = CGRectMake(0, 0, self.size.width, self.size.height) as CGRect
CGContextClipToMask(context, rect, self.CGImage)
CGContextFillRect(context, rect)
let newImage = UIGraphicsGetImageFromCurrentImageContext() as UIImage
UIGraphicsEndImageContext()
return newImage
}
}
customTabBar.swift
override func viewDidLoad() {
super.viewDidLoad()
for item in self.tabBar.items! {
item.image = item.selectedImage?.imageWithColor(unselectedColor).imageWithRenderingMode(UIImageRenderingMode.AlwaysOriginal)
//In case you wish to change the font color as well
let attributes = [NSForegroundColorAttributeName: unselectedColor]
item.setTitleTextAttributes(attributes, forState: UIControlState.Normal)
}
}
Solution 7 - Ios
There is a new appearance API in iOS 13. To color tabbar item's icon and text correctly using Xcode 11.0 you can use it like this:
if #available(iOS 13.0, *)
{
let appearance = tabBar.standardAppearance
appearance.stackedLayoutAppearance.normal.titleTextAttributes = [NSAttributedString.Key.foregroundColor: UIColor.black]
appearance.stackedLayoutAppearance.selected.titleTextAttributes = [NSAttributedString.Key.foregroundColor: UIColor.blue]
appearance.stackedLayoutAppearance.normal.iconColor = UIColor.black
appearance.stackedLayoutAppearance.selected.iconColor = UIColor.blue
tabBar.standardAppearance = appearance
}
else
{
tabBar.unselectedItemTintColor = UIColor.black
tabBar.tintColor = UIColor.blue
}
Solution 8 - Ios
I had to move the code into viewWillAppear
because in viewDidLoad
the images weren't set yet.
Swift 4 Translation
import Foundation
import UIKit
extension UIImage {
func with(color: UIColor) -> UIImage {
guard let cgImage = self.cgImage else {
return self
}
UIGraphicsBeginImageContextWithOptions(size, false, scale)
let context = UIGraphicsGetCurrentContext()!
context.translateBy(x: 0, y: size.height)
context.scaleBy(x: 1.0, y: -1.0)
context.setBlendMode(.normal)
let imageRect = CGRect(x: 0, y: 0, width: size.width, height: size.height)
context.clip(to: imageRect, mask: cgImage)
color.setFill()
context.fill(imageRect)
let newImage = UIGraphicsGetImageFromCurrentImageContext()!
UIGraphicsEndImageContext();
return newImage
}
}
class MYTabBarController: UITabBarController {
let unselectedColor = UIColor(red: 108/255.0, green: 110/255.0, blue: 114/255.0, alpha: 1.0)
let selectedColor = UIColor.blue()
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
// Unselected state colors
for item in self.tabBar.items! {
item.image = item.selectedImage!.with(color: unselectedColor).withRenderingMode(.alwaysOriginal)
}
UITabBarItem.appearance().setTitleTextAttributes([.foregroundColor : unselectedColor], for: .normal)
// Selected state colors
tabBar.tintColor = selectedColor
UITabBarItem.appearance().setTitleTextAttributes([.foregroundColor : selectedColor], for: .selected)
}
}
Solution 9 - Ios
The new answer to do this programmatically as of iOS 10+ is to use the unselectedItemTintColor
API. For example, if you have initialized your tab bar controller inside your AppDelegate
, it would looks like the following:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
...
let firstViewController = VC1()
let secondViewController = VC2()
let thirdViewController = VC3()
let tabBarCtrl = UITabBarController()
tabBarCtrl.viewControllers = [firstViewController, secondViewController, thirdViewController]
// set the color of the active tab
tabBarCtrl.tabBar.tintColor = UIColor.white
// set the color of the inactive tabs
tabBarCtrl.tabBar.unselectedItemTintColor = UIColor.gray
...
}
Solution 10 - Ios
Or just without coding. Swift 4, Xcode 10.1.
- Add
UITabBar
on your View Controller using Interface Builder. - Select the added view in the left panel.
- Type
cmd + alt + 3
or just clickShow the Identity Inspector
in the right panel. - In section
User Defined Runtime Attributes
click on plus button to add a new attribute and call it asunselectedItemTintColor
(see here). - Without leaving the section from the previous step (see number 4) under
Type
column chooseColor
type. - Finally, set the necessary color under
Value
section. - Compile your project
- Over. Congratulations.
Solution 11 - Ios
Referring to the answer from here: https://stackoverflow.com/questions/19231074/uitabbar-tint-in-ios-7
You can set the tint color for selected and unselected tab bar buttons like this:
[[UIView appearanceWhenContainedIn:[UITabBar class], nil] setTintColor:[UIColor redColor]];
[[UITabBar appearance] setSelectedImageTintColor:[UIColor greenColor]];
The first line sets the unselected color - red in this example - by setting the UIView's tintColor when it's contained in a tab bar. Note that this only sets the unselected image's tint color - it doesn't change the color of the text below it.
The second line sets the tab bar's selected image tint color to green.
Solution 12 - Ios
Swift 4 version (Without implicitly unwrapping Optionals) :
UIImage+Overlay.swift
import UIKit
extension UIImage {
func with(color: UIColor) -> UIImage? {
guard let cgImage = self.cgImage else {
return self
}
UIGraphicsBeginImageContextWithOptions(size, false, scale)
if let context = UIGraphicsGetCurrentContext() {
context.translateBy(x: 0, y: size.height)
context.scaleBy(x: 1.0, y: -1.0)
context.setBlendMode(.normal)
let imageRect = CGRect(x: 0, y: 0, width: size.width, height: size.height)
context.clip(to: imageRect, mask: cgImage)
color.setFill()
context.fill(imageRect)
if let newImage = UIGraphicsGetImageFromCurrentImageContext() {
UIGraphicsEndImageContext();
return newImage
}
}
return nil;
}
}
CustomTabBarController.swift
class CustomTabBarController: UITabBarController {
override func viewDidLoad() {
super.viewDidLoad()
if #available(iOS 10.0, *) {
self.tabBar.unselectedItemTintColor = UIColor.init(white: 1, alpha: 0.5)
} else {
// Fallback on earlier versions
if let items = self.tabBar.items {
let unselectedColor = UIColor.init(white: 1, alpha: 0.5)
let selectedColor = UIColor.white
// Unselected state colors
for item in items {
if let selectedImage = item.selectedImage?.with(color: unselectedColor)?.withRenderingMode(.alwaysOriginal) {
item.image = selectedImage
}
}
UITabBarItem.appearance().setTitleTextAttributes([NSAttributedStringKey.foregroundColor : unselectedColor], for: .normal)
// Selected state colors
tabBar.tintColor = selectedColor
UITabBarItem.appearance().setTitleTextAttributes([NSAttributedStringKey.foregroundColor : selectedColor], for: .selected)
}
}
UITabBarItem.appearance().setTitleTextAttributes([NSAttributedStringKey.font: UIFont(name: "overpass-light", size: 12)!, NSAttributedStringKey.foregroundColor: UIColor.white], for: UIControlState.normal)
}
}
Solution 13 - Ios
@JoeGalid's imageWithColor:
solution with Xamarin:
using CoreGraphics;
using UIKit;
namespace Example
{
public static class UIImageExtensions
{
public static UIImage ImageWithColor(this UIImage image, UIColor color)
{
UIGraphics.BeginImageContextWithOptions(image.Size, false, image.CurrentScale);
color.SetFill();
var context = UIGraphics.GetCurrentContext();
context.TranslateCTM(0, image.Size.Height);
context.ScaleCTM(1.0f, -1.0f);
context.SetBlendMode(CoreGraphics.CGBlendMode.Normal);
var rect = new CGRect(0, 0, image.Size.Width, image.Size.Height);
context.ClipToMask(rect, image.CGImage);
context.FillRect(rect);
var newImage = UIGraphics.GetImageFromCurrentImageContext() as UIImage;
UIGraphics.EndImageContext();
return newImage;
}
}
}
Then utilize it when setting up the tab bar items:
var image = UIImage.FromBundle("name");
barItem.Image = image.ImageWithColor(UIColor.Gray).ImageWithRenderingMode(UIImageRenderingMode.AlwaysOriginal);
barItem.SelectedImage = image.ImageWithColor(UIColor.Red).ImageWithRenderingMode(UIImageRenderingMode.AlwaysOriginal)
Solution 14 - Ios
Unselected Color of Tabbar using swift
-
Get Reference of your TabBarViewController
-
Use the following code.
[You tabbar controller name]?.tabBar.unselectedItemTintColor = [color name here]
Hope it will help.