On the iPhone, there is no such thing as a menu. When you create an application, you will usually work with a drill-down structure called NavigationController, or with the TabBarController. The difference between them is that the NavigationController ties screens together with increasing granular information, and the TabBarController lets you switch between screens which aren’t really connected to each other. It’s about that TabBarController I want to write this blog post about. Or rather, about a “missing feature” in it.
The TabBarController can be customized with either custom titles, custom icons or both. If you want custom icons, you will see that even though you created them in different colors, the iPhone SDK will always render them in blue when active, and in grey when inactive. Wouldn’t it be nice if you could have them in any color you’d like? I know designers would like that. More often than not, they design these pieces of the UI without remembering that in the end these icons will be blue/grey. But unfortunately there is no obvious way of achieving this. But when means are limited, creativity can help you solve many issues.
Custom colored icons
There is a trick to make your designer happy, and give him his colored icons. However, it still is a work around, and the method isn’t very stylish. It comes down to this:
- Don’t give icons or titles to your different UITabBarItems
- On each view of the UITabBar, set a different images as tabbar
- Each different image has both the TabBar background in it, as well as all the icons. But the currently active page icon should be highlighted
Here are some examples:
I have four tabs, so this means I need four different backgrounds for my UITabBar. On each view, I first need to remove the current background, and then I just add the background for current screen. In each ViewController I add the following:
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
for(UIView *view in self.tabBarController.tabBar.subviews) {
if([view isKindOfClass:[UIImageView class]]) {
[view removeFromSuperview];
}
}
[self.tabBarController.tabBar insertSubview:[[[UIImageView alloc] initWithImage:[UIImage imageNamed:@"background_location.png"]] autorelease] atIndex:0];
}
When you don’t remove the subviews, and just try to insert your background image at index 0, then your image won’t swap. Hence we need to remove the existing subview first, and then later insert our new one. If you now build and run your application, you should see the tabbar, and if you hit each tabbar icon, you will see that the correct one is activated. And all in color!
Update 14 Sept. 2011: I wrote a follow-up blogpost here: http://blog.theanalogguy.be/2011/09/14/custom-colored-uitabbar-icons-an-update/




25 Comments
Thanks Tom, After so much of struggling…. I found your blog and it saved my day. Thank you so much.
Pingback: Tabbar contoller through UIButtons? - Programmers Goodies
Hey ! I have similar kind of solution here . But that looks a bit simpler then this. What do you say ?
Sagar, if your solution doesn’t violate any Apple regulations, then your method is nice and elegant. I haven’t tried it myself. At the moment I wrote this article, my solution was the best I could come up with. It’s good someone found something simpler.
2bv1do onwnzprbvulp
Pingback: The Analog Guy » Custom colored UITabBar icons – an update
Is the solution provided by Didier validated by Apple (Because the overidden UITabbarItem is using private methods) ?
Hi, I have submitted an app just this summer which uses the method provided by Didier. You can check the screenshots here: http://itunes.apple.com/be/app/cultuurmarkt/id455246368?mt=8
The solution doesn’t use private methods. You are overriding private methods, but never invoking them yourself. I guess that’s fine by Apple.
Tx for your answer. Which solution did you use ?
- Are you using the 4 big tabbar view as mentioned in the blog or are you using the UITabbarItem overiding solution ?
-Can you please share your code or send me an email ?
I addressed your issues in a follow-up blogpost. You can find it here: http://blog.theanalogguy.be/2011/09/14/custom-colored-uitabbar-icons-an-update/
a small comment regarding accessibility:
Speed-scanning your post (while looking through many google-hits), the message was clear to me quickly, but the graphics confused me: 4 identical images??
Then i actually read the text and understood there should be highlighting in the images.
And indeed, now i’m aware of it’s existence, i can see the distinction between the images, but even now it requires quite some effort.
The reason is i’m colorblind, like about 10% (!!) of all males. i consider my colorblindness to be moderate, and imagine alot of people would have even more trouble seeing (the distinction between) these colors;
So it’s a great post, just not very accessible for colorblind…
It’s super easy to avoid these limitations, by using greater contrast, different colors, or even better: greater contrast AND different colors..
in general, be cautious with using red (in interfaces). IF you use it, make sure it contrasts well with the other colors your using, and NEVER use it mixed with greens and browns…
i thought you’d like to know.. hope it helps.
cheers
arri
Thanks for your feedback Arri.
I never thought about the colors as being a problem, but you’re right. If you’re colorblind this can be problematic and as such should be considered when designing the application.
As faith would have it, I was just in the process of delivering a new application, again with custom tabbar images. And guess what… all the highlight states were in red. I pointed out that this was going to be a problem for colorblind people, but there was no more time to change this.
So even if in this case I couldn’t have the designs updated, I’m now aware of this problem, and can point it out in earlier stages of development.
One fairly decent way to be sure, is to grab a screenshot, and pull out all the color in photoshop and see if you can still tell whats going on.
Most people with colorblindness can still diferentiate saturation, but have problems with various color combinations.
So say a hypothetical person that confuses red and green, using red and green (your designer will vomit before the colorblind person will though lol) at the same brightness might cause problems, but a bright and a dark one should still in theory be fine, as long as your not relying solely on color to relay information (Ie a green light for yay and a red light for boo)
For more advanced ideas on it, look up colorjack colorwheel. Other than being a great tool for coming up with stylish color combinations, you can get it to simulate various types of colorblindness and see for yourself it’ll cause folks with those conditions problems.
Pingback: GQAdonis » Implementing a Custom UITabBar
i have modified the code a little bit to give you a better behavior when it comes to detail view controllers that are pushed from a controller inside a tabbar controller.
just react on the tabs inside the app delegate (or wherever you instatiated the tabbarcontroller) like this:
- (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController
{
for(UIView *view in tabBarController.tabBar.subviews) {
if([view isKindOfClass:[UIImageView class]]) {
[view removeFromSuperview];
}
}
[tabBarController.tabBar addSubview:[[[UIImageView alloc] initWithImage:[UIImage imageNamed:[NSString stringWithFormat:@"tabbar%i.png",tabBarController.selectedIndex+1]]] autorelease]];
}
Thanks for a very helpful post.
I was wondering whether using your method violates Apple’s EULA and might get my app rejected. Has anyone who used this trick ever had his/her app published on the App Sotre
Hi Rami,
I haven’t submitted an app yet, containing this solution. However, since it doesn’t make use of private API calls or anything like that, I don’t see why it shouldn’t be approved. But until someone has confirmed this, you can’t be sure of course. It’s just some clever usage of available features.
I’ve found a solution. Just create a subclass of UITabBarItem… And you are then allowed to change the image and the associated highlighted one.
There are some example here :
http://stackoverflow.com/questions/2811905/iphone-custom-uitabbaritem-without-rounded-edges
And to have a correct image position, just play with tabItem.imageInsets :
UIEdgeInsets titleInsets = UIEdgeInsetsMake(5.0, 0.0, -6.0, 0.0);
tabItem.imageInsets = titleInsets;
Mixed with your solution, you can have a full custo tabbar
Hi,
Just a question : how do you remove the highlighted square that appears when a tabbar icon is selected ?
In your example, you are acting like there isn’t any. But on my side, I can’t make it disappear…
Thanks and thanks for this very easy way to custo the TabBar
Thank you& Thank you&
Hi Didier,
The highlighted square is automatically added by iOS. I haven’t found a way around it so far. The images in my examples were just examples for the backgrounds, not screenshots of how the application is.
Maybe it is a little late, but here goes.
The Highlighted square will always be there like Didier said, however, if you make an image that is the size of the highlighted square then this image will be on top (and the square won’t be visible).
That’s what this subclass does.
Didier has provided links to examples where you see code how to remove the highlight.
I have just recently used both a custom tabbar image & a subclass of UITabBar to remove the highlighted state of an item. Everything works fine, except if you tap the same tab twice. Then the highlight is rendered again. I have found no way around this, and assume this is something internal from cocoa
Thanks so much for this.
Haha, brilliant ! Thanks for sharing.