Episode #40

Shine Effect

10 minutes
Published on November 1, 2012

This video is only available to subscribers. Get access to this video and 578 others.

Creating an animated shine effect, similar to what you see on the slide to unlock screen on the iPhone. In this episode, I show how to achieve this effect with CALayers, layer masks, and a CABasicAnimation.

Episode Links

Adding the shine layer

We'll start by adding a CALayer on top of our imageView. The contents of the layer will be the highlighted image.

    CGFloat width = self.image.size.width;
    CGFloat height = self.image.size.height;

    CALayer *shineLayer = [CALayer layer];
    UIImage *shineImage = [UIImage imageNamed:@"logo-highlighted.png"];
    shineLayer.contents = (id)[shineImage CGImage];
    shineLayer.frame = CGRectMake(0, 1, width, height);

Adding the mask

Next we need to create another layer to mask the shine layer. This layer will be smaller, and positioned off the left side of the shine layer.

    CALayer *mask = [CALayer layer];
    mask.backgroundColor = [[UIColor clearColor] CGColor];
    UIImage *maskImage = [UIImage imageNamed:@"logo-mask.png"];
    mask.contents = (id)[maskImage CGImage];
    mask.contentsGravity = kCAGravityCenter;
    mask.frame = CGRectMake(-width, 0, width * 1.25, height);

Note that you might want to play around with the frame. Here we're creating a frame that is wider than the image we're masking so that the mask won't be initially visible.

Animating the mask

The last step is to animate the mask across the image. This is easily done with a CABasicAnimation.

    CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:@"position.x"];
    anim.byValue = @(width * 2);
    anim.repeatCount = HUGE_VALF;
    anim.duration = 3.0f;
    anim.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];

Wrapping up

The last thing we need to do is add the layers, mask the shine layer, and set the mask layer's animation.

    [self.layer addSublayer:shineLayer];
    shineLayer.mask = mask;

    [mask addAnimation:anim forKey:@"shine"];

And that's it! Pretty easy to accomplish for a neat little effect.