20

The structure is the following:

In my storyboard, I have a Tab Bar Controller which contains a Tab Bar object. This object has a custom class in which I have only this method:

- (void)awakeFromNib
{
  NSArray *imageNames = @[@"test1", @"test2", @"test3", @"test4", @"test5"];
    for (int i=0; i<5; i++) {
      UITabBarItem *item = [self.items objectAtIndex:i];
      NSString *imageName = [imageNames objectAtIndex:i];
      item.image = [[UIImage imageNamed:imageName] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
      item.selectedImage = [UIImage imageNamed:[imageName stringByAppendingString:@"-selected"]];
    }
}

I have created an Asset Catalog which contains my tab bar icons, both the selected and unselected versions (different colors).

The documentation for UIImageRenderingModeAlwaysOriginal mentions Always draw the original image, without treating it as a template. which should preserve the original image color. This doesn't seem to happen and this suggestion didn't work either.

What happens instead is that in the selected state, my tab bar icons get the default blue tint color.

One thing that I noticed is that if I do the following (taken from here) in the didFinishLaunchingWithOptions in the AppDelegate, then I can set the color of the selected tab bar icons as I want:

[[UITabBar appearance] setTintColor:[UIColor purpleColor]];

The documentation for the setTintColor mentions:

The tint color to apply to the tab bar’s tab bar items. Starting in iOS 7.0, the tint color that applies to a tab bar’s tab bar items is the first nondefault tint color in the view hierarchy, starting with the tab bar itself.

Does this mean that regardless of my tab bar icons's color (original in the images themselves), in the selected state they will always have the color of tintColor ?

Or am I doing something wrong/missing something?

I'm having this issue on iOS 7.0 and 7.1.

Community
  • 1
  • 1
Alex
  • 2,245
  • 3
  • 23
  • 33

4 Answers4

34

Just go to your image assets properties, and set Render as property to "original image"

enter image description here

And you're good to go!

Abdoelrhman
  • 875
  • 8
  • 17
28

Perfect question, really well explained.

You are not setting imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal for the selected image.

Just should add imageWithRenderingMode:UIImageRenderingModeAlwaysOriginalto the selectedImage:

  item.selectedImage = [[UIImage imageNamed:[imageName stringByAppendingString:@"-selected"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];

Check this other answer.

Community
  • 1
  • 1
Gabriel.Massana
  • 7,917
  • 6
  • 56
  • 79
  • 1
    That was it! I really didn't see that. I was so convinced that it's because the 'tintColor' overrides the color of the image. Yep, beginner mistakes. Thank you, Gabriel! Solved! – Alex Apr 03 '14 at 21:40
  • Nice but it works on second time not on the first time – JAck Oct 08 '16 at 06:41
7

Swift 3:

    for item in self.tabBar.items!{
        item.selectedImage = item.selectedImage?.withRenderingMode(.alwaysOriginal)
        item.image = item.image?.withRenderingMode(.alwaysOriginal)
    }
5

Setting non-selected image to always original render and selected one to always template render did the trick for me.

Solution for iOS 13 and swift 5.1

let item = UITabBarItem(title: "item_title",
                        image: UIImage(named: "img")?.withRenderingMode(.alwaysOriginal),
                        selectedImage: UIImage(named:"img_selected")?.withRenderingMode(.alwaysTemplate))
Mikhail Vasilev
  • 481
  • 4
  • 6