26

I'm trying to use images with template rendering mode enabled in Interface Builder but I can't get it working. With buttons everything works ok but with ImageViews the tintColor is not applying to the image.

I have enabled "Vectors type" (I'm using pdf) and "Render as Template Image" in the Image assets. What am I doing wrong?

rmvz3
  • 1,133
  • 2
  • 16
  • 27
  • 1
    This question is a duplicate of [Modify UIImage renderingMode from storyboard/xib file](http://stackoverflow.com/questions/19517334/modify-uiimage-renderingmode-from-storyboard-xib-file) – 0xced Jun 09 '15 at 19:58

4 Answers4

35

I've hit the same problem. I think this is a bug.

You could dup this radar http://openradar.appspot.com/radar?id=5334033567318016, which refers to this minimal example app https://github.com/algal/TemplateImagesBrokenDemo.

I know of two workarounds for this problem

wrap in UIButton

Since tintColor works for UIButtons, one workaround is instead of UIImageView just to use a custom-type UIButton with userInteractionEnabled=false. If you disable the button's interactivity with UIView.userInteractionEnabled (as opposed to with UIControl.enabled), then you won't change the appearance of the image.

manually re-set the image in code

Another workaround is to re-set the .image property in code, after the UIImageView has been loaded from the nib. This works because setting an image in code seems to be what triggers the templating logic. For this to work, you need to re-set the image to its existing value in a way that won't be optimized away in the compiler. A snippet like this in awakeFromNib has worked for me:

override func awakeFromNib() {
  super.awakeFromNib()

  if shouldSetImagesManually {
    // the following three-lines should in theory have no effect.
    // but in fact, they ensure that the UIImageView
    // correctly applies its tintColor to the vector template image

    let image = self.templateImageView.image
    self.templateImageView.image = nil
    self.templateImageView.image = image
  }
algal
  • 27,584
  • 13
  • 78
  • 80
11

In my case the problem occures if the app is built with iOS8 SDK and is running on iOS 7.

My workaround is:

// this is the code that *should* work and does so on iOS 8
UIColor *tintColor = [UIColor colorWithWhite:1.0 alpha:0.3];
[self.iconImageView setTintColor:tintColor];
self.iconImageView.image = [self imageForIconImageView]; // image is loaded from a pdf-resource (asset catalog set as Template) with imageNamed:@"resourceName"

// this is the workaround to get tint on iOS 7    
if (!IS_IOS8_OR_HIGHER) { // macros checking iOS version*

    UIImage *templateImage = [self.iconImageView.image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
    self.iconImageView.image = templateImage;
}

// * - macros is defined like so:
// #define IS_IOS8_OR_HIGHER ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0)
Dmitry Bondarev
  • 111
  • 1
  • 5
  • I have the same problem. Tint color can be applied to a vector image in iOS 8 as long as rendering mode is set to 'Always Template' in either IB or programmatically. But in iOS 7 the tint color only works if the image itself is set with the rendering mode then added to the image view. – JimmyJammed Mar 11 '15 at 20:50
5

Here's the simplest code-less solution I found:

set tintColor in Runtime Attributes

Zoltán
  • 1,422
  • 17
  • 22
2

Another workaround that seems to work for me is to set the controller.view's tintColor. To get the default system tint color working:

self.view.tintColor = self.view.tintColor;

Like @algal's solution, it shouldn't make a difference, but it does.

Howard Yeh
  • 61
  • 2