tymac tymac - 4 months ago 17
Swift Question

Render As Template Image on an animated WKInterfaceImage

I have a WKInterfaceImage animation with 160 frames. Animation is great. Now I want to add a tint. This SO question mentions the WatchKit tint method using the Render As Template Image option in the Inspector, but it seems it only works on a single static image. It's tinting only the last frame and it's tinting that last frame the color of my tint in the Inspector not my code tint. I have tried Rendering only the first frame and rendering all the frames to no avail.

Do I have to loop through all of them or set a range or incorporate the setTint method inside of the startAnimatingWithImagesInRange method?

enter image description here


rotateButtonImage.startAnimatingWithImagesInRange(NSRange(location: 0, length: 159), duration: 1, repeatCount: 1)

EDIT: So what I did is create an extension. It looks like this.


extension UIImage {

func imageWithTintColor(colorTint : UIColor) -> UIImage {

UIGraphicsBeginImageContextWithOptions(self.size, false, self.scale)

let context : CGContextRef = UIGraphicsGetCurrentContext()! as CGContextRef
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)
CGContextFillRect(context, rect)

let newImage : UIImage = UIGraphicsGetImageFromCurrentImageContext() as UIImage

return newImage

Then in my custom VC in
I called:

rotateButtonImage.image = rotateButtonImage.image.imageWithColor(UIColor.redColor())

But for some reason things are not auto-completing. My WKInterfaceImage is called
and I've imported Foundation and WatchKit etc.

Should my extension or function return type be of type
instead? I tried changing those but got tons of errors.

So I think I found out this extension will not work in WatchKit lol

So you have to use the Inspector method. But it's still the tint is not working on my animation. I think this may be a bug? Single image can use a tint but maybe not multiple frames even though the code is valid.


SetTintColor is only working when the image contain a single image template, as explained here.


But, actually, there is a way to recolor animatedImage. It isn't performant, and you don't wanna do this with a large set of Images.

 static func animatedImagesWithColor(color: UIColor) -> [UIImage] {
    var animatedImages = [UIImage]()

    (0...60).forEach { imageNumber in
        if let img = UIImage(named: "MyImage\(imageNumber)") {
            UIGraphicsBeginImageContextWithOptions(img.size, false, img.scale);

            let context = UIGraphicsGetCurrentContext()


            CGContextTranslateCTM(context, 0, img.size.height);
            CGContextScaleCTM(context, 1.0, -1.0);
            CGContextClipToMask(context, CGRectMake(0, 0, img.size.width, img.size.height), img.CGImage);
            CGContextFillRect(context, CGRectMake(0, 0, img.size.width, img.size.height));



    return animatedImages

You use that array this way :

let animation = UIImage.animatedImageWithImages(UIImage.animatedImagesWithColor(.redColor()), duration: 50)
let range = NSRange(location: 0, length: 60)

animationGroup.startAnimatingWithImagesInRange(range, duration: 50, repeatCount: -1)