Search code examples
iphonecocoa-touchcore-animation

CABasicAnimation in a CAGradientLayer not working - what am I doing wrong?


I have a custom UITableView cell which has a button and a label. I fire a method when someone taps on the button, and then color that row. It's all working fine.

What I want to actually do is

  1. user taps button, the row is colored in a gradient (it works now)
  2. The gradient fades away

My code is below (BackView is the view in my custom cell)

CAGradientLayer *layer = [CAGradientLayer layer];
layer.frame = BackView.bounds;

UIColor *cOne     = [UIColor paleYellowColor];
UIColor *cTwo     = [UIColor whiteColor];

NSArray *colors =  [NSArray arrayWithObjects:(id)cOne.CGColor,
                    cTwo.CGColor, nil];

layer.colors = colors;

NSNumber *stopOne     = [NSNumber numberWithFloat:0.00];
NSNumber *stopTwo     = [NSNumber numberWithFloat:0.8];

NSArray *locations = [NSArray arrayWithObjects:stopOne, stopTwo, nil];
layer.locations = locations;

CABasicAnimation *animateLayer = [CABasicAnimation animationWithKeyPath:@"colors"];
animateLayer.fromValue = [UIColor paleYellowColor];
animateLayer.toValue = [UIColor whiteColor];
animateLayer.duration   = 3.0;
animateLayer.removedOnCompletion = YES;
animateLayer.fillMode = kCAFillModeBoth;
animateLayer.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
[layer addAnimation:animateLayer forKey:@"animation"];

[BackView.layer insertSublayer:layer atIndex:0];

With this code, when I touch the button on the row, the background gets a gradient, but it never fades away, there's no animation - nothing. What am I doing wrong? I tried a few permutations and saw some examples, but none that helped me get this working.

Thanks!


Solution

  • When you animate a property with an explicit animation, you have provide the type that property is expecting. The colors property is animatable, however, you are giving it a UIColor for the from and to values. It's expecting an NSArray. Also, you need CGColorRefs for the colors themselves. I haven't tried it, but I'm thinking you need to change your to and from lines to:

    animateLayer.fromValue = [NSArray arrayWithObjects:
                             (id)[[UIColor paleYellowColor] CGColor],
                             (id)[[UIColor whiteColor] CGColor], nil];
    
    animateLayer.toValue = [NSArray arrayWithObjects:
                             (id)[[UIColor whiteColor] CGColor],
                             (id)[[UIColor whiteColor] CGColor], nil];
    

    In theory, this should fade from your yellow/white gradient to white/white which should give the effect of fading out.

    Best regards.