1

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.setImageNamed("frame")

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

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

WKImage+Tint.swift

extension UIImage {

func imageWithTintColor(colorTint : UIColor) -> UIImage {

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

    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
    UIGraphicsEndImageContext()

    return newImage
}
}

Then in my custom VC in awakeWithContext I called:

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

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

Should my extension or function return type be of type WKInterfaceImage 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.

Community
  • 1
  • 1
Edison
  • 11,881
  • 5
  • 42
  • 50

1 Answers1

2

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

https://developer.apple.com/library/ios/documentation/WatchKit/Reference/WKInterfaceImage_class/index.html#//apple_ref/occ/instm/WKInterfaceImage/setTintColor:

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()

            color.setFill()

            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));

            animatedImages.append(UIGraphicsGetImageFromCurrentImageContext())
            UIGraphicsEndImageContext()

        }
    }

    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.setBackgroundImage(animation)
animationGroup.startAnimatingWithImagesInRange(range, duration: 50, repeatCount: -1)
Victor Carmouze
  • 947
  • 6
  • 10