40

Is it possible to use custom colors and background images in a UITabBar? I realize that Apple would like everyone to use the same blue and gray tab bars, but is there any way to customize this?

Second, even I were to create my own TabBar-like view controller, along with custom images, would this violate Apple's Human Interface Guidelines?

icodebuster
  • 8,890
  • 7
  • 62
  • 65
pix0r
  • 31,139
  • 18
  • 86
  • 102
  • There have been some warnings below of these methods being somewhat risky in terms of Apple's rules... can you confirm that any of them were successfully approved by the AppStore? – Chazbot May 15 '11 at 00:52
  • Possible duplicate: http://stackoverflow.com/questions/1355480/preventing-a-uitabbar-from-applying-a-gradient-to-its-icon-images/ – rpetrich Aug 31 '09 at 09:07

12 Answers12

30

I found an answer to this at Silent Mac Design.

I implemented this way:

First make a subclass of UITabBarContoller

// CustomUITabBarController.h

#import <UIKit/UIKit.h>

@interface CustomUITabBarController: UITabBarController {
  IBOutlet UITabBar *tabBar1;
}

@property(nonatomic, retain) UITabBar *tabBar1;

@end

 

// CustomUITabBarController.m

#import "CustomUITabBarController.h"

@implementation CustomUITabBarController

@synthesize tabBar1;

- (void)viewDidLoad {
  [super viewDidLoad];

  CGRect frame = CGRectMake(0.0, 0, self.view.bounds.size.width, 48);

  UIView *v = [[UIView alloc] initWithFrame:frame];

  [v setBackgroundColor:[[UIColor alloc] initWithRed:1.0
                                               green:0.0
                                                blue:0.0
                                               alpha:0.1]];

  [tabBar1 insertSubview:v atIndex:0];
  [v release];
}

@end

And in your Nib file replace the class of your TabBar Controller with CustomUITabBarController.

Sophie Alpert
  • 139,698
  • 36
  • 220
  • 238
Filiberto Cota
  • 340
  • 2
  • 4
  • 8
    This worked for me with the following change: I subclassed UITabBar rather than UITabBarController, I overrode `-drawRect:(CGRect)rect` instead of `-viewDidLoad`, and I put my tint UIView in as a subview of `self`. – Dan Ray Aug 24 '10 at 13:24
  • 3
    This had no effect at all. Also, Mac Design seems a gone site. This answer should be checked incorrect... – Jonny Nov 11 '10 at 07:54
  • 7
    Although this works, Apple specifically says in their docs to not subclass UITabBarController. So do it at your own risk. – bpapa Jan 18 '11 at 20:31
20

FYI, from iOS 5 onwards you can customize various aspects of the UITabBar, including setting its background image using the backgroundImage property.

The new UITabBar "Customizing Appearance" properties in iOS 5 are:

backgroundImage 
selectedImageTintColor  
selectionIndicatorImage  
tintColor  

Given that Apple have introduced these methods in iOS 5, then it's possible they may be more sympathetic to attempts to customize the UITabBar for earlier OSes. This website says the Twitter app uses a custom tab bar, so that might be more reason that Apple would let such an app into the App Store, it's no guarantee though!

Dan J
  • 25,433
  • 17
  • 100
  • 173
14

Use Following images ( Assuming, tabBar is having 5 Tabs as follows )

  • enter image description here
  • enter image description here
  • enter image description here
  • enter image description here
  • enter image description here

Create a new project using - "TabBar Application" template & Place following code.

Contents of AppDel.h File.

#import <UIKit/UIKit.h>

@interface cTabBarAppDelegate : NSObject <UIApplicationDelegate, UITabBarControllerDelegate> {

}

@property (nonatomic, retain) IBOutlet UIWindow *window;
@property (nonatomic, retain) IBOutlet UITabBarController *tabBarController;
@property (nonatomic, retain) IBOutlet UIImageView *imgV;

@end

Contents of AppDel.m File.

#import "cTabBarAppDelegate.h"

@implementation cTabBarAppDelegate
@synthesize window=_window;
@synthesize tabBarController=_tabBarController;
@synthesize imgV = _imgV;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.tabBarController.delegate=self;
    self.imgV.frame=CGRectMake(0, 425, 320, 55);
    [self.tabBarController.view addSubview:self.imgV];
    self.tabBarController.selectedIndex=0;
    self.window.rootViewController = self.tabBarController;
    [self.window makeKeyAndVisible];
    return YES;
}

- (BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController{
    NSUInteger index=[[tabBarController viewControllers] indexOfObject:viewController];
    switch (index) {
        case 0:
            self.imgV.image=[UIImage imageNamed:@"tBar1.png"];
            break;
        case 1:
            self.imgV.image=[UIImage imageNamed:@"tBar2.png"];
            break;
        case 2:
            self.imgV.image=[UIImage imageNamed:@"tBar3.png"];
            break;
        case 3:
            self.imgV.image=[UIImage imageNamed:@"tBar4.png"];
            break;
        case 4:
            self.imgV.image=[UIImage imageNamed:@"tBar5.png"];
            break;
        default:
            break;
    }
    return YES;
}
Dori
  • 915
  • 1
  • 12
  • 20
sagarkothari
  • 24,520
  • 50
  • 165
  • 235
9

At the beginning of ***ViewController.m add the following might help set background image of UITabBar.


@implementation UITabBar (CustomImage)
- (void)drawRect:(CGRect)rect {
    UIImage *image = [UIImage imageNamed: @"background.png"];
    [image drawInRect:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)];
}
@end
Richard Chen
  • 237
  • 4
  • 3
  • good approach but it replaces the background of tthe whole tab bar and you do not have chance to change tab bar icon color? – Ilker Baltaci Oct 18 '12 at 14:59
6

If you want to use custom colors for the icons (and not just the background) instead of the default gray and blue, do it like this: http://blog.theanalogguy.be/2010/10/06/custom-colored-uitabbar-icons/

Basically, you need to create complete tabbar images (background and icons and text) for each selected tab and set your UITabBarItems to no icon and no title and insert the image into the tabbar as an UIImageView in viewWillAppear:

And Apple won't mind since we are not using any private APIs.

4

Since iOS 7.0, you can use -[UIImage imageWithRenderingMode:] with UIImageRenderingModeAlwaysOriginal to preserve colors:

// Preserve the colors of the tabs.
UITabBarController *controller = (UITabBarController *)((UIWindow *)[UIApplication sharedApplication].windows[0]).rootViewController;

NSArray *onIcons = @[ @"tab1-on", @"tab2-on", @"tab3-on" ];
NSArray *offIcons = @[ @"tab1-off", @"tab2-off", @"tab3-off" ];
NSArray *items = controller.tabBar.items;
for (NSUInteger i = 0; i < items.count; ++i) {
    UITabBarItem *item = items[i];
    item.image = [[UIImage imageNamed:offIcons[i]] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
    item.selectedImage = [[UIImage imageNamed:onIcons[i]] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
}

Works like a charm.

emp
  • 3,350
  • 1
  • 22
  • 19
  • Great answer! Better still, you can set the rendering mode on the image in the Assets folder without a single line of code... – Felipe Ferri Jul 20 '16 at 22:20
2

In AppDelegate.m

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[[UITabBar appearance] setSelectedImageTintColor:[UIColor redColor]];
return YES;
}
Vineesh TP
  • 7,755
  • 12
  • 66
  • 130
1

Its possible without adding any subView.

In the class where you define the tab bar set the property of the tabBarItem to ->>

UITabBarItem *tabBarItem1 = [[self.tabBar.tabBar items] objectAtIndex:0];
[tabBarItem1 setFinishedSelectedImage:[UIImage imageNamed:@"campaigns_hover.png"] withFinishedUnselectedImage:[UIImage imageNamed:@"campaigns.png"]];

Its a property of tabBarItem and u can change the default blue image to a custom image. campaigns_hover.png is the selected custom image AND campaigns.png is the custom image when not selected...

Enjoy the secret.. :)

NiKKi
  • 3,296
  • 3
  • 29
  • 39
1

Here's the document that says we can't change pressed or selected appearance with our icons.

https://developer.apple.com/iphone/library/documentation/UserExperience/Conceptual/MobileHIG/IconsImages/IconsImages.html#//apple_ref/doc/uid/TP40006556-CH14-SW1

It's under the heading Icons for Navigation Bars, Toolbars, and Tab Bars

binbash
  • 149
  • 3
  • 8
1

As far as the UITabBar class is concerned, the icons in the bar are limited to the colours: blue for selected and grey for unselected. This is because the tab bar only uses the alpha value from the icons you supply to create the image on the bar.

The bar itself is limited to being black, as far as I can remember. I've not seen anything like the 'tint' property on UINavigationBar in the docs.

I guess you could go ahead and create your own tab bar style class and do what you want with it, but I have absolutely no idea how that fits in with Apple's HIG, or whether or not they'd challenge it during the review process.

In my experience, Apple reviewers only rejected my app if I didn't use THEIR UI elements according to the HIG. They might have a different view when it's your own UI elements you're playing with.

Jasarien
  • 58,279
  • 31
  • 157
  • 188
  • UInavigationBar has a tint property self.navigationController.navigationBar.tintColor = [UIColor grayColor]; – RVN Apr 27 '10 at 14:18
  • If you read my answer, I'm not talking about UINavigationBar. I'm talking about UITabBar, and how **it** doesn't have a tint property like the navigation bar does. - 1 for you sir. – Jasarien Apr 27 '10 at 15:14
0

The below code helps you to add custom colors with RGB values to ur tabBar.

self.tabBarController.tabBar.tintColor = [[UIColor alloc] initWithRed:0.00
                                                                green:0.62
                                                                 blue:0.93
                                                                alpha:1.0];
Pradeep Reddy Kypa
  • 3,992
  • 7
  • 57
  • 75
0

You can do that without -insertSubview:atIndex, because a new UIView is not needed. You can apply a theme using QuartzCore on each view (UITabBar and it's subviews). So the UITabBar's background is added as I've described here.

Now we must apply the image on each UITabBarItem as it's background:

    // UITabBar+CustomItem.h
    #import <UIKit/UIKit.h>
    #import <QuartzCore/QuartzCore.h>

    @interface UITabBar (CustomItem)
    -(void)setSelectedItemBackground:(UIImage *)backgroundImage;
    @end

Now the .m file:

    // UITabBar+CustomItem.m

    @implementation UITabBar (CustomItem)

    #define kItemViewTag      445533  // <-- casual number
    #define kItemViewOldTag   445599  // <-- casual number different from the above

    -(void)setSelectedItemBackground:(UIImage *)backgroundImage   {
        UIView *oldView = [self viewWithTag:kImageViewItemTag];
        oldView.layer.contents = nil;  // <-- remove the previous background
        oldView.tag = kItemViewOldTag;  // <-- this will avoid problems

        NSUInteger index = [self.items indexOfObject:self.selectedItem];
        UIView *buttonView = [self.subviews objectAtIndex:index];
        buttonView.tag = kItemViewTag;
        buttonView.layer.contents = (id)backgroundImage.CGImage;  // <-- add 
        // the new background
    }

    @end

You can also change the color of the selected images, as someone made here. But what I'm wondering is: can I change the color of the selected label? The answer is yes, as described below (the following works on ios 3.x/4.x, not iOS5+):

    @implementation UITabBar (Custom)

    #define kSelectedLabel  334499  // <-- casual number        

    -(void)changeCurrentSelectedLabelColor:(UIColor *)color  {
        UIView *labelOldView = [self viewWithTag:kSelectedLabel];
        [labelOldView removeFromSuperview];

        NSString *selectedText = self.selectedItem.title;
        for(UIView *subview in self.subviews)  {
            if ([NSStringFromClass([subview class]) 
                      isEqualToString:@"UITabBarButton"])  {
                for(UIView *itemSubview in subview.subviews)  {
                    if ([itemSubview isKindOfClass:[UILabel class]])  {
                         UILabel *itemLabel = (UILabel *)itemSubview;
                         if([itemLabel.text isEqualToString:selectedText])  {
                              UILabel *selectedLabel = [[UILabel alloc]
                                               initWithFrame:itemLabel.bounds];
                              selectedLabel.text = itemLabel.text;
                              selectedLabel.textColor = color;
                              selectedLabel.font = itemLabel.font;
                              selectedLabel.tag = kSelectedLabel;
                              selectedLabel.backgroundColor = [UIColor clearColor];
                              [itemSubview addSubview:selectedLabel];
                              [selectedLabel release];
                         }
                    }
                }

            }
        }
    }

    @end 
Community
  • 1
  • 1