When I make icons for a UITabBar, it applies a gradient to the images. I need to know how to prevent it from having this gradient.
Apple added tab bar customization in iOS 5, and now this kind of stuff is trivial. Prior to this it was a huge hack, and not recommended.
Here's how to do a completely custom tab bar:
// custom icons
UITabBarItem *item = [[UITabBarItem alloc] init];
item.title = @"foo";
// setting custom images prevents the OS from applying a tint color
[item setFinishedSelectedImage:[UIImage imageNamed:@"tab1_active.png"] withFinishedUnselectedImage:[UIImage imageNamed:@"tab1_image_deselected.png"]];
tab1ViewController.tabBarItem = item;
// tab bar
// set background image - will be used instead of glossy black
tabBarController.tabBar.backgroundImage = [UIImage imageNamed:@"tab_bar_bg.png"];
// optionally set the tint color - setting this ti nil will result in the standard, blue tint color. tint color is ignored when custom icons are set as above.
tabBarController.tabBar.selectedImageTintColor = nil;
// remove the highlight around the selected tab - or provide an alternate highlight image. If you don't do this the iOS default is to draw a highlighted box beneath the selected tab icon.
tabBarController.tabBar.selectionIndicatorImage = [[UIImage alloc] init];
This is surprisingly difficult as the UITabBar
doesn't provide access to it's selected/unselected images. It can be achieved with a private API though:
@interface UITabBar (ColorExtensions)
- (void)recolorItemsWithColor:(UIColor *)color shadowColor:(UIColor *)shadowColor shadowOffset:(CGSize)shadowOffset shadowBlur:(CGFloat)shadowBlur;
@end
@interface UITabBarItem (Private)
@property(retain, nonatomic) UIImage *selectedImage;
- (void)_updateView;
@end
@implementation UITabBar (ColorExtensions)
- (void)recolorItemsWithColor:(UIColor *)color shadowColor:(UIColor *)shadowColor shadowOffset:(CGSize)shadowOffset shadowBlur:(CGFloat)shadowBlur
{
CGColorRef cgColor = [color CGColor];
CGColorRef cgShadowColor = [shadowColor CGColor];
for (UITabBarItem *item in [self items])
if ([item respondsToSelector:@selector(selectedImage)] &&
[item respondsToSelector:@selector(setSelectedImage:)] &&
[item respondsToSelector:@selector(_updateView)])
{
CGRect contextRect;
contextRect.origin.x = 0.0f;
contextRect.origin.y = 0.0f;
contextRect.size = [[item selectedImage] size];
// Retrieve source image and begin image context
UIImage *itemImage = [item image];
CGSize itemImageSize = [itemImage size];
CGPoint itemImagePosition;
itemImagePosition.x = ceilf((contextRect.size.width - itemImageSize.width) / 2);
itemImagePosition.y = ceilf((contextRect.size.height - itemImageSize.height) / 2);
UIGraphicsBeginImageContext(contextRect.size);
CGContextRef c = UIGraphicsGetCurrentContext();
// Setup shadow
CGContextSetShadowWithColor(c, shadowOffset, shadowBlur, cgShadowColor);
// Setup transparency layer and clip to mask
CGContextBeginTransparencyLayer(c, NULL);
CGContextScaleCTM(c, 1.0, -1.0);
CGContextClipToMask(c, CGRectMake(itemImagePosition.x, -itemImagePosition.y, itemImageSize.width, -itemImageSize.height), [itemImage CGImage]);
// Fill and end the transparency layer
CGContextSetFillColorWithColor(c, cgColor);
contextRect.size.height = -contextRect.size.height;
CGContextFillRect(c, contextRect);
CGContextEndTransparencyLayer(c);
// Set selected image and end context
[item setSelectedImage:UIGraphicsGetImageFromCurrentImageContext()];
UIGraphicsEndImageContext();
// Update the view
[item _updateView];
}
}
@end
One can even create some pretty cool effects:
(source: booleanmagic.com)
It is very possible that Apple will reject an application for doing this. If the private API is removed in a future OS update, -[UITabBar recolorItemsWithColor:shadowColor:shadowOffset:shadowBlur:]
will do nothing instead of crashing.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With