87

The UINavigationBar and UISearchBar both have a tintColor property that allows you to change the tint color (surprising, I know) of both of those items. I want to do the same thing to the UITabBar in my application, but have found now way to change it from the default black color. Any ideas?

TheNeil
  • 1,985
  • 2
  • 17
  • 36
pixel
  • 5,269
  • 8
  • 33
  • 32
  • These are great answers. If you're allowing autorotation, it's helpful to set the autoresizingMask of the subview to have flexible margins and size, or the new background won't resize with the tab bar. – pmdj Jul 02 '10 at 16:52

18 Answers18

105

iOS 5 has added some new appearance methods for customising the look of most UI elements.

You can target every instance of a UITabBar in your app by using the appearance proxy.

For iOS 5 + 6:

[[UITabBar appearance] setTintColor:[UIColor redColor]];

For iOS 7 and above, please use the following:

[[UITabBar appearance] setBarTintColor:[UIColor redColor]];

Using the appearance proxy will change any tab bar instance throughout the app. For a specific instance, use one of the new properties on that class:

UIColor *tintColor; // iOS 5+6
UIColor *barTintColor; // iOS 7+
UIColor *selectedImageTintColor;
UIImage *backgroundImage;
UIImage *selectionIndicatorImage;
imnk
  • 4,327
  • 3
  • 27
  • 31
  • 3
    Nope. As I pointed out, they are for iOS 5. You can always target specific versions with conditional compilation statements: http://cocoawithlove.com/2010/07/tips-tricks-for-conditional-ios3-ios32.html – imnk Dec 21 '11 at 10:53
  • Thanks, that was helpful :) Never knew there was such thing. – Veeru Jul 30 '12 at 09:23
  • For iOS 7, use [UITabBar appearance] setBarTintColor, if you want to change background color – Zeezer Jul 29 '14 at 11:30
47

I have been able to make it work by subclassing a UITabBarController and using private classes:

@interface UITabBarController (private)
- (UITabBar *)tabBar;
@end

@implementation CustomUITabBarController


- (void)viewDidLoad {
    [super viewDidLoad];

    CGRect frame = CGRectMake(0.0, 0.0, self.view.bounds.size.width, 48);
    UIView *v = [[UIView alloc] initWithFrame:frame];
    [v setBackgroundColor:kMainColor];
    [v setAlpha:0.5];
    [[self tabBar] addSubview:v];
    [v release];

}
@end
coneybeare
  • 33,248
  • 21
  • 128
  • 182
  • 1
    This is sort of an odd solution in that it just places semi transparent brown rectangle on top of the tabbar. The problem is that all the buttons are turned brown, not just the background. However this seems to be the best option anyone's presented so far. – Jonah Aug 18 '09 at 20:04
  • is this a private API? if i used this in my app would i get refused? – Frank Nov 16 '10 at 18:23
  • there doesnt appear to be any private calls in there no – Anthony Main Nov 25 '10 at 18:02
  • the tabbar property used to not be accessible. – coneybeare Nov 26 '10 at 18:24
  • this modifies the tabbar background, not the "selected item" highlight, which i would be more interested in – smdvlpr Nov 27 '10 at 20:33
  • Right… the original poster asked for background color changes… This is also a very old question and answer and there are better ways to do it now – coneybeare Nov 28 '10 at 00:37
  • you can change the highlights by subclassing UITabBarItem: http://stackoverflow.com/questions/3461867/is-there-a-way-to-use-a-custom-selected-image-for-uitabbaritem – Frank Nov 30 '10 at 19:48
  • your actually just placing a kMainColor colored view on top of the tabBar. but if you add [self.tabBar sendSubviewToBack:v]; just before the [v release]; you will be able to press the buttons actually – Edward Ashak Mar 23 '11 at 18:34
34

I have an addendum to the final answer. While the essential scheme is correct, the trick of using a partially transparent color can be improved upon. I assume that it's only for letting the default gradient to show through. Oh, also, the height of the TabBar is 49 pixels rather than 48, at least in OS 3.

So, if you have a appropriate 1 x 49 image with a gradient, this is the version of viewDidLoad you should use:

- (void)viewDidLoad {

    [super viewDidLoad]; 

    CGRect frame = CGRectMake(0, 0, 480, 49);
    UIView *v = [[UIView alloc] initWithFrame:frame];
    UIImage *i = [UIImage imageNamed:@"GO-21-TabBarColorx49.png"];
    UIColor *c = [[UIColor alloc] initWithPatternImage:i];
    v.backgroundColor = c;
    [c release];
    [[self tabBar] addSubview:v];
    [v release];

}
Tim
  • 38,263
  • 17
  • 115
  • 131
pabugeater
  • 341
  • 3
  • 2
  • 1
    if you want to make it pretty with a background picture, see this: http://duivesteyn.net/2010/01/16/iphone-custom-tabbar-background-image/ – oberbaum Feb 12 '10 at 12:58
  • 1
    I think it needs to be: [[self tabBar] insertSubview:v atIndex:0]; – Vibhor Goyal Aug 17 '10 at 20:49
  • I know the answer is old but that worked for me. Since i needed a custom image instead of a color, i mixed your answer with this one [tint on bars - UITabBar part](http://letstalkcocoa.com/2009/12/applying-tint-to-bars/) – RaphaelDDL Nov 18 '11 at 19:25
27

When you just use addSubview your buttons will lose clickability, so instead of

[[self tabBar] addSubview:v];

use:

[[self tabBar] insertSubview:v atIndex:0];
xpda
  • 15,014
  • 8
  • 47
  • 78
Marcin Zbijowski
  • 790
  • 1
  • 7
  • 23
7

On iOS 7:

[[UITabBar appearance] setBarTintColor:[UIColor colorWithRed:(38.0/255.0) green:(38.0/255.0) blue:(38.0/255.0) alpha:1.0]];

I also recommend setting first depending on your visual desires:

[[UITabBar appearance] setBarStyle:UIBarStyleBlack];

The bar style puts a subtle separator between your view content and your tab bar.

capikaw
  • 10,150
  • 1
  • 39
  • 46
7

There is no simple way to do this, you basically need to subclass UITabBar and implement custom drawing to do what you want. It is quite a bit of work for the effect, but it may be worth it. I recommend filing a bug with Apple to get it added to a future iPhone SDK.

Louis Gerbarg
  • 42,998
  • 8
  • 77
  • 88
7

Following is the perfect solution for this. This works fine with me for iOS5 and iOS4.

//---- For providing background image to tabbar
UITabBar *tabBar = [tabBarController tabBar]; 

if ([tabBar respondsToSelector:@selector(setBackgroundImage:)]) {
    // ios 5 code here
    [tabBar setBackgroundImage:[UIImage imageNamed:@"image.png"]];
} 
else {
    // ios 4 code here
    CGRect frame = CGRectMake(0, 0, 480, 49);
    UIView *tabbg_view = [[UIView alloc] initWithFrame:frame];
    UIImage *tabbag_image = [UIImage imageNamed:@"image.png"];
    UIColor *tabbg_color = [[UIColor alloc] initWithPatternImage:tabbag_image];
    tabbg_view.backgroundColor = tabbg_color;
    [tabBar insertSubview:tabbg_view atIndex:0];
}
El Developer
  • 3,261
  • 1
  • 18
  • 40
Gaurav
  • 7,651
  • 4
  • 31
  • 55
5

for me its very simple to change the color of Tabbar like :-

[self.TabBarController.tabBar setTintColor:[UIColor colorWithRed:0.1294 green:0.5686 blue:0.8353 alpha:1.0]];


[self.TabBarController.tabBar setTintColor:[UIColor "YOUR COLOR"];

Try this!!!

Muhammad Rizwan
  • 3,450
  • 1
  • 23
  • 35
5

[[self tabBar] insertSubview:v atIndex:0]; works perfectly for me.

Legolas
  • 11,767
  • 11
  • 73
  • 129
jimmy
  • 203
  • 4
  • 4
3
 [[UITabBar appearance] setTintColor:[UIColor redColor]];
 [[UITabBar appearance] setBarTintColor:[UIColor yellowColor]];
Hsm
  • 1,430
  • 15
  • 16
2

for just background color

Tabbarcontroller.tabBar.barTintColor=[UIColor redcolour];

or this in App Delegate

[[UITabBar appearance] setBackgroundColor:[UIColor blackColor]];

for changing color of unselect icons of tabbar

For iOS 10:

// this code need to be placed on home page of tabbar    
for(UITabBarItem *item in self.tabBarController.tabBar.items) {
    item.image = [item.image imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
}

Above iOS 10:

// this need to be in appdelegate didFinishLaunchingWithOptions
[[UITabBar appearance] setUnselectedItemTintColor:[UIColor blackColor]];
Vaibhav Gaikwad
  • 306
  • 5
  • 12
1

There are some good ideas in the existing answers, many work slightly differently and what you choose will also depend on which devices you target and what kind of look you're aiming to achieve. UITabBar is notoriously unintuitive when it come to customizing its appearance, but here are a few more tricks that may help:

1). If you're looking to get rid of the glossy overlay for a more flat look do:

tabBar.backgroundColor = [UIColor darkGrayColor]; // this will be your background
[tabBar.subviews[0] removeFromSuperview]; // this gets rid of gloss

2). To set custom images to the tabBar buttons do something like:

for (UITabBarItem *item in tabBar.items){
    [item setFinishedSelectedImage:selected withFinishedUnselectedImage:unselected];
    [item setImageInsets:UIEdgeInsetsMake(6, 0, -6, 0)];
}

Where selected and unselected are UIImage objects of your choice. If you'd like them to be a flat colour, the simplest solution I found is to create a UIView with the desired backgroundColor and then just render it into a UIImage with the help of QuartzCore. I use the following method in a category on UIView to get a UIImage with the view's contents:

- (UIImage *)getImage {
    UIGraphicsBeginImageContextWithOptions(self.bounds.size, NO, [[UIScreen mainScreen]scale]);
    [[self layer] renderInContext:UIGraphicsGetCurrentContext()];
    UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return viewImage;
}

3) Finally, you may want to customize the styling of the buttons' titles. Do:

for (UITabBarItem *item in tabBar.items){
    [item setTitleTextAttributes: [NSDictionary dictionaryWithObjectsAndKeys:
                [UIColor redColor], UITextAttributeTextColor,
                [UIColor whiteColor], UITextAttributeTextShadowColor,
                [NSValue valueWithUIOffset:UIOffsetMake(0, 1)], UITextAttributeTextShadowOffset,
                [UIFont boldSystemFontOfSize:18], UITextAttributeFont,
            nil] forState:UIControlStateNormal];
}

This lets you do some adjustments, but still quite limited. Particularly, you cannot freely modify where the text is placed within the button, and cannot have different colours for selected/unselected buttons. If you want to do more specific text layout, just set UITextAttributeTextColor to be clear and add your text into the selected and unselected images from part (2).

SaltyNuts
  • 4,658
  • 8
  • 43
  • 77
1
[v setBackgroundColor ColorwithRed: Green: Blue: ];
MaxEcho
  • 13,325
  • 6
  • 72
  • 84
0
if ([tabBar respondsToSelector:@selector(setBackgroundImage:)]) {
    // ios 5 code here
    [tabBar setBackgroundImage:[UIImage imageNamed:@"image.png"]];
} 
else {
    // ios 4 code here
    CGRect frame = CGRectMake(0, 0, 480, 49);
    UIView *tabbg_view = [[UIView alloc] initWithFrame:frame];
    UIImage *tabbag_image = [UIImage imageNamed:@"image.png"];
    UIColor *tabbg_color = [[UIColor alloc] initWithPatternImage:tabbag_image];
    tabbg_view.backgroundColor = tabbg_color;
    [tabBar insertSubview:tabbg_view atIndex:0];
}
0

Swift 3.0 answer: (from Vaibhav Gaikwad)

For changing color of unselect icons of tabbar:

if #available(iOS 10.0, *) {
        UITabBar.appearance().unselectedItemTintColor = UIColor.white
    } else {
        // Fallback on earlier versions
        for item in self.tabBar.items! {
            item.image = item.image?.withRenderingMode(UIImageRenderingMode.alwaysOriginal)
        }
}

For changing text color only:

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

UITabBarItem.appearance().setTitleTextAttributes([NSForegroundColorAttributeName: UIColor.red, for: .selected)
odemolliens
  • 2,431
  • 2
  • 28
  • 33
0

Swift 3 using appearance from your AppDelegate do the following:

UITabBar.appearance().barTintColor = your_color

Bobj-C
  • 5,487
  • 8
  • 44
  • 75
0

Another solution (which is a hack) is to set the alpha on the tabBarController to 0.01 so that it is virtually invisible yet still clickable. Then set a an ImageView control on the bottom of the MainWindow nib with your custom tabbar image underneath the alpha'ed tabBarCOntroller. Then swap the images, change colors or hightlight when the tabbarcontroller switches views.

However, you lose the '...more' and customize functionality.

user855723
  • 21
  • 4
0

Hi There am using iOS SDK 4 and i was able to solve this issue with just two lines of code and it's goes like this

tBar.backgroundColor = [UIColor clearColor];
tBar.backgroundImage = [UIImage imageNamed:@"your-png-image.png"];

Hope this helps!