以前写过一篇文章:自定义标签栏,这篇文章提供了另一种自定义标签栏的方式。
CustomTabBarViewController.h
#import "CustomTabBar.h" @interface CustomTabBarViewController : UIViewController <CustomTabBarDelegate> { CustomTabBar *tabBar; } @property (nonatomic, retain) CustomTabBar *tabBar; @end
CustomTabBarViewController.m
#import "CustomTabBarViewController.h" #define SELECTED_VIEW_CONTROLLER_TAG 98456345 static NSArray *tabBarItems = nil; @implementation CustomTabBarViewController @synthesize tabBar; - (void) awakeFromNib { UIViewController *detailController1 = [[[UIViewController alloc] init] autorelease]; detailController1.view.backgroundColor = [UIColor redColor]; UIViewController *detailController2 = [[[UIViewController alloc] init] autorelease]; detailController2.view.backgroundColor = [UIColor whiteColor]; UIViewController *detailController3 = [[[UIViewController alloc] init] autorelease]; detailController3.view.backgroundColor = [UIColor blueColor]; UIViewController *detailController4 = [[[UIViewController alloc] init] autorelease]; detailController4.view.backgroundColor = [UIColor cyanColor]; UIViewController *detailController5 = [[[UIViewController alloc] init] autorelease]; detailController5.view.backgroundColor = [UIColor purpleColor]; tabBarItems = [[NSArray arrayWithObjects: [NSDictionary dictionaryWithObjectsAndKeys:@"chat.png", @"image", detailController1, @"viewController", nil], [NSDictionary dictionaryWithObjectsAndKeys:@"compose-at.png", @"image", detailController2, @"viewController", nil], [NSDictionary dictionaryWithObjectsAndKeys:@"messages.png", @"image", detailController3, @"viewController", nil], [NSDictionary dictionaryWithObjectsAndKeys:@"magnifying-glass.png", @"image", detailController4, @"viewController", nil], [NSDictionary dictionaryWithObjectsAndKeys:@"more.png", @"image", detailController5, @"viewController", nil], nil] retain]; } - (void)viewDidLoad { [super viewDidLoad]; UIImage *tabBarGradient = [UIImage imageNamed:@"TabBarGradient.png"]; self.tabBar = [[[CustomTabBar alloc] initWithItemCount:tabBarItems.count itemSize:CGSizeMake(self.view.frame.size.width / tabBarItems.count, tabBarGradient.size.height * 2) tag:0 delegate:self] autorelease]; tabBar.frame = CGRectMake(0, self.view.frame.size.height - (tabBarGradient.size.height * 2), self.view.frame.size.width, tabBarGradient.size.height * 2); [self.view addSubview:tabBar]; [tabBar selectItemAtIndex:0]; [self touchDownAtItemAtIndex:0]; } #pragma mark - #pragma mark CustomTabBarDelegate - (UIImage *) imageFor:(CustomTabBar *)tabBar atIndex:(NSUInteger)itemIndex { NSDictionary *data = [tabBarItems objectAtIndex:itemIndex]; return [UIImage imageNamed:[data objectForKey:@"image"]]; } - (UIImage *) backgroundImage { CGFloat width = self.view.frame.size.width; UIImage *topImage = [UIImage imageNamed:@"TabBarGradient.png"]; UIGraphicsBeginImageContextWithOptions(CGSizeMake(width, topImage.size.height * 2), NO, 0.0); UIImage *stretchedTopImage = [topImage stretchableImageWithLeftCapWidth:0 topCapHeight:0]; [stretchedTopImage drawInRect:CGRectMake(0, 0, width, topImage.size.height)]; [[UIColor blackColor] set]; CGContextFillRect(UIGraphicsGetCurrentContext(), CGRectMake(0, topImage.size.height, width, topImage.size.height)); UIImage *resultImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return resultImage; } - (UIImage *) selectedItemBackgroundImage { return [UIImage imageNamed:@"TabBarItemSelectedBackground.png"]; } - (UIImage *) glowImage { UIImage *tabBarGlow = [UIImage imageNamed:@"TabBarGlow.png"]; UIGraphicsBeginImageContextWithOptions(CGSizeMake(tabBarGlow.size.width, tabBarGlow.size.height - 4.0), NO, 0.0); [tabBarGlow drawAtPoint:CGPointZero]; UIImage *resultImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return resultImage; } - (UIImage *) selectedItemImage { UIImage *tabBarGradient = [UIImage imageNamed:@"TabBarGradient.png"]; CGSize tabBarItemSize = CGSizeMake(self.view.frame.size.width / tabBarItems.count, tabBarGradient.size.height * 2); UIGraphicsBeginImageContextWithOptions(tabBarItemSize, NO, 0.0); [[[UIImage imageNamed:@"TabBarSelection.png"] stretchableImageWithLeftCapWidth:4.0 topCapHeight:0] drawInRect:CGRectMake(0, 4.0, tabBarItemSize.width, tabBarItemSize.height - 4.0)]; UIImage *selectedItemImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return selectedItemImage; } - (UIImage *) tabBarArrowImage { return [UIImage imageNamed:@"TabBarNipple.png"]; } - (void) touchDownAtItemAtIndex:(NSUInteger)itemIndex { UIView *currentView = [self.view viewWithTag:SELECTED_VIEW_CONTROLLER_TAG]; [currentView removeFromSuperview]; NSDictionary *data = [tabBarItems objectAtIndex:itemIndex]; UIViewController *viewController = [data objectForKey:@"viewController"]; UIImage *tabBarGradient = [UIImage imageNamed:@"TabBarGradient.png"]; viewController.view.frame = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height - (tabBarGradient.size.height * 2)); viewController.view.tag = SELECTED_VIEW_CONTROLLER_TAG; [self.view insertSubview:viewController.view belowSubview:tabBar]; [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(addGlowTimerFireMethod:) userInfo:[NSNumber numberWithInteger:itemIndex] repeats:NO]; } - (void)addGlowTimerFireMethod:(NSTimer *)theTimer { for (NSUInteger i = 0 ; i < tabBarItems.count ; i++) { [tabBar removeGlowAtIndex:i]; } [tabBar glowItemAtIndex:[[theTimer userInfo] integerValue]]; } - (void)dealloc { [tabBar release]; [super dealloc]; } @end
CustomTabBar.h
@class CustomTabBar; @protocol CustomTabBarDelegate - (UIImage *) imageFor:(CustomTabBar *)tabBar atIndex:(NSUInteger)itemIndex; - (UIImage *) backgroundImage; - (UIImage *) selectedItemBackgroundImage; - (UIImage *) glowImage; - (UIImage *) selectedItemImage; - (UIImage *) tabBarArrowImage; @optional - (void) touchUpInsideItemAtIndex:(NSUInteger)itemIndex; - (void) touchDownAtItemAtIndex:(NSUInteger)itemIndex; @end @interface CustomTabBar : UIView { NSObject <CustomTabBarDelegate> *delegate; NSMutableArray *buttons; } @property (nonatomic, retain) NSMutableArray *buttons; - (id) initWithItemCount:(NSUInteger)itemCount itemSize:(CGSize)itemSize tag:(NSInteger)objectTag delegate:(NSObject <CustomTabBarDelegate> *)customTabBarDelegate; - (void) selectItemAtIndex:(NSInteger)index; - (void) glowItemAtIndex:(NSInteger)index; - (void) removeGlowAtIndex:(NSInteger)index; @end
CustomTabBar.m
#import "CustomTabBar.h" #define GLOW_IMAGE_TAG 2394858 #define TAB_ARROW_IMAGE_TAG 2394859 @interface CustomTabBar (PrivateMethods) - (CGFloat) horizontalLocationFor:(NSUInteger)tabIndex; - (void) addTabBarArrowAtIndex:(NSUInteger)itemIndex; - (UIButton *) buttonAtIndex:(NSUInteger)itemIndex width:(CGFloat)width; - (UIImage *) tabBarImage:(UIImage *)startImage size:(CGSize)targetSize backgroundImage:(UIImage *)backgroundImage; - (UIImage *) blackFilledImageWithWhiteBackgroundUsing:(UIImage *)startImage; - (UIImage *) tabBarBackgroundImageWithSize:(CGSize)targetSize backgroundImage:(UIImage *)backgroundImage; @end @implementation CustomTabBar @synthesize buttons; - (id) initWithItemCount:(NSUInteger)itemCount itemSize:(CGSize)itemSize tag:(NSInteger)objectTag delegate:(NSObject <CustomTabBarDelegate> *)customTabBarDelegate { if (self = [super init]) { self.tag = objectTag; delegate = customTabBarDelegate; UIImage *backgroundImage = [delegate backgroundImage]; UIImageView *backgroundImageView = [[[UIImageView alloc] initWithImage:backgroundImage] autorelease]; backgroundImageView.frame = CGRectMake(0, 0, backgroundImage.size.width, backgroundImage.size.height); [self addSubview:backgroundImageView]; self.frame = CGRectMake(0, 0, itemSize.width * itemCount, itemSize.height); self.buttons = [[NSMutableArray alloc] initWithCapacity:itemCount]; CGFloat horizontalOffset = 0; for (NSUInteger i = 0 ; i < itemCount ; i++) { UIButton *button = [self buttonAtIndex:i width:self.frame.size.width / itemCount]; [button addTarget:self action:@selector(touchDownAction:) forControlEvents:UIControlEventTouchDown]; [button addTarget:self action:@selector(touchUpInsideAction:) forControlEvents:UIControlEventTouchUpInside]; [button addTarget:self action:@selector(otherTouchesAction:) forControlEvents:UIControlEventTouchUpOutside]; [button addTarget:self action:@selector(otherTouchesAction:) forControlEvents:UIControlEventTouchDragOutside]; [button addTarget:self action:@selector(otherTouchesAction:) forControlEvents:UIControlEventTouchDragInside]; [buttons addObject:button]; button.frame = CGRectMake(horizontalOffset, 0.0, button.frame.size.width, button.frame.size.height); [self addSubview:button]; horizontalOffset = horizontalOffset + itemSize.width; } } return self; } - (void) dimAllButtonsExcept:(UIButton *)selectedButton { for (UIButton *button in buttons) { if (button == selectedButton) { button.selected = YES; button.highlighted = button.selected ? NO : YES; UIImageView *tabBarArrow = (UIImageView *)[self viewWithTag:TAB_ARROW_IMAGE_TAG]; NSUInteger selectedIndex = [buttons indexOfObjectIdenticalTo:button]; if (tabBarArrow) { [UIView beginAnimations:nil context:nil]; [UIView setAnimationDuration:0.2]; CGRect frame = tabBarArrow.frame; frame.origin.x = [self horizontalLocationFor:selectedIndex]; tabBarArrow.frame = frame; [UIView commitAnimations]; } else { [self addTabBarArrowAtIndex:selectedIndex]; } } else { button.selected = NO; button.highlighted = NO; } } } - (void)touchDownAction:(UIButton *)button { [self dimAllButtonsExcept:button]; if ([delegate respondsToSelector:@selector(touchDownAtItemAtIndex:)]) [delegate touchDownAtItemAtIndex:[buttons indexOfObject:button]]; } - (void)touchUpInsideAction:(UIButton *)button { [self dimAllButtonsExcept:button]; if ([delegate respondsToSelector:@selector(touchUpInsideItemAtIndex:)]) [delegate touchUpInsideItemAtIndex:[buttons indexOfObject:button]]; } - (void)otherTouchesAction:(UIButton *)button { [self dimAllButtonsExcept:button]; } - (void) selectItemAtIndex:(NSInteger)index { UIButton *button = [buttons objectAtIndex:index]; [self dimAllButtonsExcept:button]; } - (void) glowItemAtIndex:(NSInteger)index { UIButton *button = [buttons objectAtIndex:index]; UIImage *glowImage = [delegate glowImage]; UIImageView *glowImageView = [[[UIImageView alloc] initWithImage:glowImage] autorelease]; glowImageView.frame = CGRectMake(button.frame.size.width / 2.0 - glowImage.size.width / 2.0, button.frame.origin.y + button.frame.size.height - glowImage.size.height, glowImage.size.width, glowImage.size.height); glowImageView.tag = GLOW_IMAGE_TAG; [button addSubview:glowImageView]; } - (void) removeGlowAtIndex:(NSInteger)index { UIButton *button = [buttons objectAtIndex:index]; UIImageView *glowImageView = (UIImageView *)[button viewWithTag:GLOW_IMAGE_TAG]; [glowImageView removeFromSuperview]; } - (CGFloat) horizontalLocationFor:(NSUInteger)tabIndex { UIImageView *tabBarArrow = (UIImageView *)[self viewWithTag:TAB_ARROW_IMAGE_TAG]; CGFloat tabItemWidth = self.frame.size.width / buttons.count; CGFloat halfTabItemWidth = (tabItemWidth / 2.0) - (tabBarArrow.frame.size.width / 2.0); return (tabIndex * tabItemWidth) + halfTabItemWidth; } - (void) addTabBarArrowAtIndex:(NSUInteger)itemIndex { UIImage *tabBarArrowImage = [delegate tabBarArrowImage]; UIImageView *tabBarArrow = [[[UIImageView alloc] initWithImage:tabBarArrowImage] autorelease]; tabBarArrow.tag = TAB_ARROW_IMAGE_TAG; CGFloat verticalLocation = -tabBarArrowImage.size.height + 2; tabBarArrow.frame = CGRectMake([self horizontalLocationFor:itemIndex], verticalLocation, tabBarArrowImage.size.width, tabBarArrowImage.size.height); [self addSubview:tabBarArrow]; } - (UIButton *) buttonAtIndex:(NSUInteger)itemIndex width:(CGFloat)width { UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom]; button.frame = CGRectMake(0.0, 0.0, width, self.frame.size.height); UIImage *rawButtonImage = [delegate imageFor:self atIndex:itemIndex]; UIImage *buttonImage = [self tabBarImage:rawButtonImage size:button.frame.size backgroundImage:nil]; UIImage *buttonPressedImage = [self tabBarImage:rawButtonImage size:button.frame.size backgroundImage:[delegate selectedItemBackgroundImage]]; [button setImage:buttonImage forState:UIControlStateNormal]; [button setImage:buttonPressedImage forState:UIControlStateHighlighted]; [button setImage:buttonPressedImage forState:UIControlStateSelected]; [button setBackgroundImage:[delegate selectedItemImage] forState:UIControlStateHighlighted]; [button setBackgroundImage:[delegate selectedItemImage] forState:UIControlStateSelected]; button.adjustsImageWhenHighlighted = NO; return button; } - (UIImage *) tabBarImage:(UIImage *)startImage size:(CGSize)targetSize backgroundImage:(UIImage *)backgroundImageSource { UIImage *backgroundImage = [self tabBarBackgroundImageWithSize:startImage.size backgroundImage:backgroundImageSource]; UIImage *bwImage = [self blackFilledImageWithWhiteBackgroundUsing:startImage]; CGImageRef imageMask = CGImageMaskCreate(CGImageGetWidth(bwImage.CGImage), CGImageGetHeight(bwImage.CGImage), CGImageGetBitsPerComponent(bwImage.CGImage), CGImageGetBitsPerPixel(bwImage.CGImage), CGImageGetBytesPerRow(bwImage.CGImage), CGImageGetDataProvider(bwImage.CGImage), NULL, YES); CGImageRef tabBarImageRef = CGImageCreateWithMask(backgroundImage.CGImage, imageMask); UIImage *tabBarImage = [UIImage imageWithCGImage:tabBarImageRef scale:startImage.scale orientation:startImage.imageOrientation]; CGImageRelease(imageMask); CGImageRelease(tabBarImageRef); UIGraphicsBeginImageContextWithOptions(targetSize, NO, 0.0); [tabBarImage drawInRect:CGRectMake((targetSize.width / 2.0) - (startImage.size.width / 2.0), (targetSize.height / 2.0) - (startImage.size.height / 2.0), startImage.size.width, startImage.size.height)]; UIImage *resultImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return resultImage; } - (UIImage *) blackFilledImageWithWhiteBackgroundUsing:(UIImage *)startImage { CGRect imageRect = CGRectMake(0, 0, CGImageGetWidth(startImage.CGImage), CGImageGetHeight(startImage.CGImage)); CGContextRef context = CGBitmapContextCreate(NULL, imageRect.size.width, imageRect.size.height, 8, 0, CGImageGetColorSpace(startImage.CGImage), kCGImageAlphaPremultipliedLast); CGContextSetRGBFillColor(context, 1, 1, 1, 1); CGContextFillRect(context, imageRect); CGContextClipToMask(context, imageRect, startImage.CGImage); CGContextSetRGBFillColor(context, 0, 0, 0, 1); CGContextFillRect(context, imageRect); CGImageRef newCGImage = CGBitmapContextCreateImage(context); UIImage* newImage = [UIImage imageWithCGImage:newCGImage scale:startImage.scale orientation:startImage.imageOrientation]; CGContextRelease(context); CGImageRelease(newCGImage); return newImage; } - (UIImage *) tabBarBackgroundImageWithSize:(CGSize)targetSize backgroundImage:(UIImage *)backgroundImage { UIGraphicsBeginImageContextWithOptions(targetSize, NO, 0.0); if (backgroundImage) { [backgroundImage drawInRect:CGRectMake((targetSize.width - CGImageGetWidth(backgroundImage.CGImage)) / 2, (targetSize.height - CGImageGetHeight(backgroundImage.CGImage)) / 2, CGImageGetWidth(backgroundImage.CGImage), CGImageGetHeight(backgroundImage.CGImage))]; } else { [[UIColor lightGrayColor] set]; UIRectFill(CGRectMake(0, 0, targetSize.width, targetSize.height)); } UIImage *finalBackgroundImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return finalBackgroundImage; } - (void)dealloc { [buttons release]; [super dealloc]; } @end
示例图: