For Gigster’s navigation concept it was necessary to implement a custom styled tab bar. Basically the screen is divided into three parts:
- Navigation Bar
- Tab Bar
- Content
The navigation bar has a custom background image and a fixed title with custom font. The tab bar should be directly under the navigation bar and has complete custom styling.
Basic Setup
To start off I created a new Xcode project and added a UITabBarController with three static views. Although I have XIBs for each content view, I added everything else in code. Each view has a UINavigationController so it can easily contain its own navigation stack.
Navigation Bar
An easy technique to get a custom background in a UINavigationBar is to make a cateogory. Add this code (e.g. in YourAppDelegate.m):
@end
@implementation UINavigationBar (MyCustomNavBar)
- (void) drawRect:(CGRect)rect
{
UIImage *barImage = [UIImage imageNamed:@"nav_bg.png"];
[barImage drawInRect:rect];
}
@end
To get the fixed title with custom font I added a method that creates a UILabel:
{
CGRect frame = CGRectMake(0, 0, 320, 44);
UILabel *label = [[[UILabel alloc] initWithFrame:frame] autorelease];
label.backgroundColor = [UIColor clearColor];
label.font = [UIFont fontWithName:@"Marker Felt" size:24];
label.shadowColor = [UIColor colorWithWhite:0.0 alpha:0.5];
label.textAlignment = UITextAlignmentCenter;
label.textColor = [UIColor whiteColor];
label.text = @"Custom Tab Bar";
return label;
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
...
// add static title labels
[tab1NavigationController.navigationBar addSubview:[self _makeTitleLabel]];
[tab2NavigationController.navigationBar addSubview:[self _makeTitleLabel]];
[tab3NavigationController.navigationBar addSubview:[self _makeTitleLabel]];
...
}
Tab Bar
A little bit of frame hackery was necessary to get the tab bar right beneath the navigation bar:
tabBarController.tabBar.autoresizingMask = 0;
tabBarController.tabBar.frame = CGRectMake(0, 44, 320, 65);
// fix frame of tabbarcontroller's view
CGRect frame = tabBarController.view.frame;
frame.size.height += 29;
frame.origin.y = 20;
tabBarController.view.frame = frame;
To have a custom layout for the tab bar, it is necessary to subclass UITabBarController. We don’t need UIKit’s tab bar at all, so we just hide it and create our own custom tabs:
{
// find the normal tab bar and hide it
for(UIView *view in self.view.subviews)
{
if([view isKindOfClass:[UITabBar class]])
{
view.hidden = YES;
break;
}
}
[self _setupCustomTabBar];
}
First I added a UIImageView containing a background image:
{
// background image
self.bgImageView = [[[UIImageView alloc] initWithImage:[UIImage imageNamed:@"tabs_bg.png"]] autorelease];
bgImageView.frame = CGRectMake(0, 44, 320, 65);
[self.view addSubview:bgImageView];
Next we want to display a tab image to indicate which tab is active:
[self.view addSubview:self.contentView];
// sliding tab image
self.tabImage = [[[UIImageView alloc] initWithImage:[UIImage imageNamed:@"tab.png"]] autorelease];
CGRect frame = self.tabImage.frame;
frame.origin = CGPointMake(BUTTON_X_OFFSET, BUTTON_Y);
self.tabImage.frame = frame;
[self.contentView addSubview:self.tabImage];
Finally I added three buttons to trigger tab selection:
[self.contentView addSubview:[self _makeTabButtonWithTitle:@"Tab 1" atIndex:0]];
[self.contentView addSubview:[self _makeTabButtonWithTitle:@"Tab 2" atIndex:1]];
[self.contentView addSubview:[self _makeTabButtonWithTitle:@"Tab 3" atIndex:2]];
}
Button creation method:
atIndex:(NSInteger)index
{
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
button.frame = CGRectMake(BUTTON_X_OFFSET + index*BUTTON_WIDTH, BUTTON_Y, BUTTON_WIDTH, BUTTON_HEIGHT);
button.tag = index;
button.titleLabel.font = [UIFont fontWithName:@"Marker Felt" size:18];
button.titleLabel.shadowColor = [UIColor colorWithWhite:0 alpha:0.5];
button.titleLabel.shadowOffset = CGSizeMake(0, -1);
[button setTitle:title forState:UIControlStateNormal];
[button addTarget:self action:@selector(_buttonClicked:) forControlEvents:UIControlEventTouchUpInside];
return button;
}
Note that the buttons’ action is _buttonClicked. There we need to set the currently selected tab index in the UITabBarController.
{
self.selectedIndex = [sender tag];
[self _updateTabImage];
}
We also want to update the tab image’s position after a tab was selected. This is what _updateTabImage is for:
{
CGRect targetRect = CGRectMake(BUTTON_X_OFFSET + self.selectedIndex*BUTTON_WIDTH, BUTTON_Y, BUTTON_WIDTH, BUTTON_HEIGHT);
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.3];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[self.tabImage setFrame:targetRect];
[UIView commitAnimations];
}
Now we have a fully functioning tab bar with custom layout. You can download the full Xcode project here:MyCustomTabBar_final.zip.
Gigster in the App Store: Jump
'iOS' 카테고리의 다른 글
[iOS] UIImage 이미지 비율에 맞춰 스케일 재조정하기 (0) | 2012.09.03 |
---|---|
iOS5 Customizing Navigation Bar (네비게이션바 커스터마이징) (0) | 2012.09.03 |
맥/iOS용 tcp/udp 라이브러리 CocoaAsyncSocket (0) | 2012.08.29 |
iOS5에서 NSJSONSerialization을 사용해서 JSON 다루기 예제 (0) | 2012.08.28 |
GCD와 Block을 이용해서 비동기 방식으로 URL 이미지 로드하기 (0) | 2012.08.27 |