CAGradientLayer properties not animating within UIView animation block

前端 未结 2 2043
长发绾君心
长发绾君心 2020-12-31 09:19

I have a feeling I\'m overlooking something elementary, but what better way to find it than to be wrong on the internet?

I have a fairly basic UI. The view for my

2条回答
  •  星月不相逢
    2020-12-31 09:50

    You have to use explicit CAAnimations, because you're changing the value of a CALayer. UIViewAnimations work on UIView properties, but not directly on their CALayer's properties...

    Actually, you should use a CABasicAnimation so that you can access its fromValue and toValue properties.

    The following code should work for you:

    -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
        [UIView animateWithDuration:2.0f
                              delay:0.0f
                            options:UIViewAnimationCurveEaseInOut
                         animations:^{
                             CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"colors"];
                             animation.duration = 2.0f;
                             animation.delegate = self;
                             animation.fromValue = ((CAGradientLayer *)self.layer).colors;
                             animation.toValue = [NSArray arrayWithObjects:(id)[UIColor blackColor].CGColor,(id)[UIColor whiteColor].CGColor,nil];
                             [self.layer addAnimation:animation forKey:@"animateColors"];
                         }
                         completion:nil];
    }
    
    -(void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag {
        NSString *keyPath = ((CAPropertyAnimation *)anim).keyPath;
        if ([keyPath isEqualToString:@"colors"]) {
            ((CAGradientLayer *)self.layer).colors = ((CABasicAnimation *)anim).toValue;
        }
    }
    

    There is a trick with CAAnimations in that you HAVE to explicitly set the value of the property AFTER you complete the animation.

    You do this by setting the delegate, in this case I set it to the object which calls the animation, and then override its animationDidStop:finished: method to include the setting of the CAGradientLayer's colors to their final value.

    You'll also have to do a bit of casting in the animationDidStop: method, to access the properties of the animation.

提交回复
热议问题