views:

393

answers:

1

Similar to this previous question, I want to apply an arbitrarly-coloured tint to an arbitrary image (a UIImageView). However, I want the tint to fade away over N seconds of time, to have a "pulse" effect. I'll be triggering the pulse every M seconds.

While I think I could rig up a naive solution using an NSTimer to change the tint, I think I can probably use some of the Core Animation framework to have a much more elegant (and efficient) solution. However, I'm not very familiar with Core Animation.

Is creating a "pulse" like this possible with Core Animation? If so, how?

+1  A: 

If you're planning to use Core Animation, the approach will be different than what was demonstrated in your link to a previous SO question. Instead, create a layer that uses the color you're after for the tint and then animate that layer's opacity. Something like this:

CALayer *tintLayer = [CALayer layer];

// Center the layer on the view
[tintLayer setBounds:[imageView bounds]];
[tintLayer setPosition:CGPointMake([imageView bounds].size.width/2.0, 
                                   [imageView bounds].size.height/2.0)];

// Fill the color
[tintLayer setBackgroundColor:
           [[UIColor colorWithRed:0.5 green:0.5 blue:0.0 alpha:1.0] CGColor]];
[tintLayer setOpacity:0.5];
[[imageView layer] addSublayer:tintLayer];

// Add the animation
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"opacity"];
[animation setFromValue:[NSNumber numberWithFloat:0.5]];
[animation setToValue:[NSNumber numberWithFloat:0.0]];
// Animate back to the starting value automatically
[animation setAutoreverses:YES];
// Animate over the course of 5 seconds.
[animation setDuration:5.0];

[tintLayer addAnimation:animation forKey:@"opacity"];

The only question I'm not sure about is whether it will work the same since we don't specify a blend mode in the tint layer. I will have to look and see what blending is occurring by default with CA.

Best regards.

UPDATE: Found another SO post that says that blending in CA depends on the layer's 'opaque' property.

Matt Long
Will this work if the aforementioned arbitrary image is not rectangular (like a circle), or just has a border of blank space around it (pixels with 0 alpha)? Because if you're calling setBackgroundColor:, you're going to set a colour to those pixels that aren't supposed to be "lit up".
Shaggy Frog
Right, it's going to tint the whole rectangle. I think this would also be true with the the other Core Graphics approach, though. I'm not sure about that, though, as I haven't tried it.
Matt Long