It’s been a while I haven’t written anything about iPhone :) Anyways, today I added a fancy UITabBar (like in #Tweetie 2) to 1.1 version of my application (Zaman). I thought I would share the code since I saw lots of iPhone Dev folks are looking for this :)
Initially I started googling, then I ended up a StackOverflow entry says you have to Roll it :) Since my need was just placing an indicator on top of the UITabItem, I didn’t go for that way.
Here is how I did:
First, I created an UIImageView which has the indicator icon. Then I added this view to my UITabBar as subview.
UIImage *upArrow = [UIImage imageNamed:@"up-arrow.png"]; UIImageView *imageView=[[UIImageView alloc] initWithImage:upArrow]; imageView.tag = ICON_TAG; [upArrow release]; [self.tabBarController.tabBar addSubview:imageView];
This wasn’t quite enough for my need since I needed indicator to be centered. So I did some math :)
int itemCount = [self.tabBarController.tabBar.items count]; CGFloat cellWidth = tabBarController.view.frame.size.width/itemCount; CGFloat center = (cellWidth / 2) - (INDICATOR_WIDTH / 2);
Now I could easily use this center as my indicator center. However I noticed that this wasn’t enough either since I want it to move every time after I tap to the next UITabBarItem. So I did some refactoring and:
#define INDICATOR_WIDTH 10 //u can define st like this
-(void) addIndicatorTo:(int) index {
int itemCount = [self.tabBarController.tabBar.items count];
CGFloat cellWidth=tabBarController.view.frame.size.width/itemCount;
CGFloat center = (index * cellWidth) + (cellWidth / 2)
- (INDICATOR_WIDTH / 2);
UIImage *upArrow = [UIImage imageNamed:@"up-arrow.png"];
UIImageView *imageView = [[UIImageView alloc] initWithImage:upArrow];
imageView.tag = ICON_TAG;
[upArrow release];
[self.tabBarController.tabBar addSubview:imageView];
}
// just listen the item index change
- (void)tabBarController:(UITabBarController *)tbController
didSelectViewController:(UIViewController *)viewController {
[self addIndicatorTo:tbController.selectedIndex];
}
So far so good. Wait a second, this adds new images every time I tap to the next UITabBarItem :S Anyways, so I refactored my code a little more:
#define INDICATOR_WIDTH 10, u can define st like this
#define INDICATOR_WIDTH 9, u can define st like this
#define ICON_TAG 11, u can define st like this
-(UIImageView *) createNewIndicator {
UIImage *upArrow = [UIImage imageNamed:@"up-arrow.png"];
UIImageView *imageView = [[UIImageView alloc] initWithImage:upArrow];
imageView.tag = ICON_TAG;
[upArrow release];
return imageView;
}
-(UIImageView *) findIndicator {
// return existing one
for (UIView *view in self.tabBarController.tabBar.subviews) {
if (view.tag == ICON_TAG) {
return (UIImageView *) view;
}
}
// if not return a new one
return [self createNewIndicator];
}
-(void) addIndicatorTo:(int) index {
int itemCount = [self.tabBarController.tabBar.items count];
CGFloat cellWidth = tabBarController.view.frame.size.width / itemCount;
CGFloat center = (index * cellWidth)
+ (cellWidth / 2) - (INDICATOR_WIDTH / 2);
UIImageView *imageView = [self findIndicator];
imageView.frame = CGRectMake(
indicatorPositionX,
3 - INDICATOR_HEIGHT,
INDICATOR_WIDTH,
INDICATOR_HEIGHT
);
[self.tabBarController.tabBar addSubview:imageView];
}
This is basically it. So I did some animation too, here is the result:
If you guys need, I can upload the working source code to somewhere.. Hope this guides a bit.










Why don’t you use UITabBarController? I usually have the same effect with less work.
December 9, 2009, 5:57 AMFor 2 reasons, first saving UITabItem positions and reloading them back when application starts cause problems. You’re ending up an inconsistent layout. Second, it is a best practice to handle UITabItem selections in the application delegate if you have only one UITabBar view.
December 9, 2009, 10:03 AMI thing there is something wrong with the first piece of code: UIImage *upArrow = [UIImage imageNamed:@"up-arrow.png"]; is alreadt autorelased image (not new/alloc/copy) [upArrow release]; // it can cause a problem but *imageView is not released and should cause a leak
December 9, 2009, 8:42 PMCan you provide a source, may be the video is too small to see what the difference Thanks.
December 9, 2009, 8:43 PM@andrew, I’m not re-creating the up-arrow view every time. It’s tagging the view on first create and use it every time it moves. So it won’t cause any memory leak at that point. I’ll provide the source, u can see it there.
December 10, 2009, 12:56 AMWhere is a good place to get icons for use in my tabbars???
January 25, 2010, 10:12 AM