I experimented and based on this answer , found a way to do what I want, without subclassing UITabBarItem or UITabBar!
Basically, the idea is to create a UIImage method that mimics the behavior of a UITabBar shade mask, and also renders it in its โoriginalโ form and avoids its own shade mask.
All you have to do is create a new UIImage instance method that returns the masked image with the desired color:
@interface UIImage(Overlay) - (instancetype)tabBarImageWithCustomTint:(UIColor *)tintColor; @end @implementation UIImage(Overlay) - (instancetype)tabBarImageWithCustomTint:(UIColor *)tintColor { UIGraphicsBeginImageContextWithOptions(self.size, NO, self.scale); CGContextRef context = UIGraphicsGetCurrentContext(); CGContextTranslateCTM(context, 0, self.size.height); CGContextScaleCTM(context, 1.0, -1.0); CGContextSetBlendMode(context, kCGBlendModeNormal); CGRect rect = CGRectMake(0, 0, self.size.width, self.size.height); CGContextClipToMask(context, rect, self.CGImage); [tintColor setFill]; CGContextFillRect(context, rect); UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); newImage = [newImage imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal]; return newImage; } @end
This is a fairly simple version of the code in the answer I posted, with one exception: the returned image has its own rendering mode, always unchanged, which ensures that the default UITabBar mask will not be applied. Now all that is needed is to use this method when editing a tab bar item:
navController.tabBarItem = [[UITabBarItem alloc] initWithTitle:@"title" image:normal_image selectedImage:[selected_image tabBarImageWithCustomTint:[UIColor redColor]]];
Needless to say, selected_image is a normal image, which is obtained from UIImage imageNamed: and [UIColor redColor can be replaced with any desired color.
element119
source share