Change only one hue color of UITabBarItem

It is well known that the hue color of selected (or active) elements in the UITabBarController can be easily changed, here is an example:

myBarController.tabBar.tintColor = [UIColor redColor]; 

In this case, any element of the tab bar in the tabBar will have a red tint as soon as it becomes active. Again, this applies to all elements of this tab bar.

How can the active color of shades differ from other elements of the tab bar in one line? For example, one element may have a red tint when selected, while another may have a blue tint.

I know that this can probably be solved by redrawing and subclassing the entire tab bar. However, this is the only change I need and it seems redundant. I am not trying to change the style and how the elements are rendered in any way, just to make this style different between different elements.

I have not seen any answers to this question anywhere that are related to updates in iOS 7 and 8.

+7
ios ios7 ios8 uitabbaritem
source share
5 answers

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.

+2
source share

There is a much easier way to do this! Add this to the ViewController, the UITabBar element should be in a different color

 - (void) viewWillAppear:(BOOL)animated { // change tint color to red [self.tabBarController.tabBar setTintColor:[UIColor redColor]]; [super viewWillAppear: animated]; } 

Paste this into other ViewControllers

 - (void) viewWillAppear:(BOOL)animated { // change tint color to black [self.tabBarController.tabBar setTintColor:[UIColor blackColor]]; [super viewWillAppear: animated]; } 

I use this to get different hue colors in each ViewController for example: [red | black | green | pink]

+9
source share

@ element119 solution using swift (for you, lazy guys):

 extension UIImage { func tabBarImageWithCustomTint(tintColor: UIColor) -> UIImage { UIGraphicsBeginImageContextWithOptions(self.size, false, self.scale) let context: CGContextRef = UIGraphicsGetCurrentContext() CGContextTranslateCTM(context, 0, self.size.height) CGContextScaleCTM(context, 1.0, -1.0) CGContextSetBlendMode(context, kCGBlendModeNormal) let rect: CGRect = CGRectMake(0, 0, self.size.width, self.size.height) CGContextClipToMask(context, rect, self.CGImage) tintColor.setFill() CGContextFillRect(context, rect) var newImage: UIImage = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() newImage = newImage.imageWithRenderingMode(UIImageRenderingMode.AlwaysOriginal) return newImage } } 

I use this code to tint the middle red icon:

 if let items = self.tabBar.items as? [UITabBarItem] { let button = items[1] button.image = button.image?.tabBarImageWithCustomTint(UIColor.redColor()) } 
+3
source share

It worked for me! code for Swift 3

 extension UIImage { func tabBarImageWithCustomTint(tintColor: UIColor) -> UIImage { UIGraphicsBeginImageContextWithOptions(self.size, false, self.scale) let context: CGContext = UIGraphicsGetCurrentContext()! context.translateBy(x: 0, y: self.size.height) context.scaleBy(x: 1.0, y: -1.0) context.setBlendMode(CGBlendMode(rawValue: 1)!) let rect: CGRect = CGRect(x: 0, y: 0, width: self.size.width, height: self.size.height) context.clip(to: rect, mask: self.cgImage!) tintColor.setFill() context.fill(rect) var newImage: UIImage = UIGraphicsGetImageFromCurrentImageContext()! UIGraphicsEndImageContext() newImage = newImage.withRenderingMode(UIImageRenderingMode.alwaysOriginal) return newImage } } 

and after...

  button.image = button.image?.tabBarImageWithCustomTint(tintColor: UIColor(red: 30.0/255.0, green: 33.0/255.0, blue: 108.0/255.0, alpha: 1.0)) 

thanks;))

+2
source share

swift xcode7.1:

 extension UIImage { func tabBarImageWithCustomTint(tintColor: UIColor) -> UIImage { UIGraphicsBeginImageContextWithOptions(self.size, false, self.scale) let context: CGContextRef = UIGraphicsGetCurrentContext()! CGContextTranslateCTM(context, 0, self.size.height) CGContextScaleCTM(context, 1.0, -1.0) CGContextSetBlendMode(context, CGBlendMode.Normal) let rect: CGRect = CGRectMake(0, 0, self.size.width, self.size.height) CGContextClipToMask(context, rect, self.CGImage) tintColor.setFill() CGContextFillRect(context, rect) var newImage: UIImage = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() newImage = newImage.imageWithRenderingMode(UIImageRenderingMode.AlwaysOriginal) return newImage } } 

compatibility bug fixed in @Binsh answer

0
source share

All Articles