确定一个动画周期的结束

时间:2013-09-07 16:40:55

标签: iphone ios animation

这是一个有点棘手的搜索。不太确定该如何敲击Google或SO,所以如果以前已经回答过,我会道歉。

所以我有两个动画,我应用于持续时间为5秒的CALayer(尽管这不相关)并且它们无限重复。我希望能够在用户交互中优雅地删除这些动画。

检测交互很容易,但能够确定动画何时到达一个周期的结束并不容易。通过检测这一点,我希望能够实现动画效果,最后一个循环并停止,而不是严格地将其从屏幕上移除,看起来显得不友好。

这就是我现在正在做的事情,它无法正常工作

- (void)attachFadeAnimation {

    // Create a fade animation that compliments the scale such that
    // the layer will become totally transparent 1/5 of the way
    // through the animation.
    CAKeyframeAnimation *fadeAnimation = [CAKeyframeAnimation animationWithKeyPath:@"opacity"];
    fadeAnimation.values = @[@0.8, @0, @0];

    [self addAnimation:fadeAnimation withKeyPath:@"opacity"];

}

- (void)addAnimation:(CAKeyframeAnimation *)animation withKeyPath:(NSString *)keyPath {

    // These are all shared values of the animations and therefore
    // make more sense to be added here. Any changes here will
    // change each animation.
    animation.keyTimes = @[@0, @0.2, @1];
    animation.repeatCount = HUGE_VALF;
    animation.duration = 5.0f;
    animation.delegate = self;

    [self.layer addAnimation:animation forKey:keyPath];

}

- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag {

    if ( !self.emanating )
        [self.layer removeAllAnimations];

}

当我期待它时,不会调用对animationDidStop:finished的委托调用。显然我误解了文档。

1 个答案:

答案 0 :(得分:2)

好的,因此无法使用委托方法来实现这一点,我搜索了Apple CoreAnimation文档,发现与我的视图关联的CALayer带有presentationLayer属性,该属性描述了当前屏幕上显示的内容。

使用这个我能够创建另一个动画来更优雅地“结束”第一个动画。

此代码实际上来自与原始文件不同的文件,但我希望实现的效果是相同的:

- (void)alert {

    CABasicAnimation *flashAnimation = [CABasicAnimation animationWithKeyPath:@"backgroundColor"];
    flashAnimation.duration = 1.0f;
    flashAnimation.autoreverses = YES;
    flashAnimation.repeatCount = HUGE_VALF;
    flashAnimation.fromValue = (id)self.view.backgroundColor.CGColor;
    flashAnimation.toValue = (id)[UIColor colorWithRed:0.58f green:0.23f blue:0.14f alpha:1.0f].CGColor;

    [self.view.layer addAnimation:flashAnimation forKey:@"alert"];

}

- (void)cancelAlert {

    // Remove the flashing animation from the view layer.
    [self.view.layer removeAnimationForKey:@"alert"];

    // Using the views presentation layer I can interpolate the background
    // colour back to the original colour after removing the flashing
    // animation.
    CALayer *presentationLayer = (CALayer *)[self.view.layer presentationLayer];

    CABasicAnimation *resetBackground = [CABasicAnimation animationWithKeyPath:@"backgroundColor"];
    resetBackground.duration = 1.0f;
    resetBackground.fromValue = (id)presentationLayer.backgroundColor;
    resetBackground.toValue = (id)_originalBackgroundColor.CGColor;

    [self.view.layer addAnimation:resetBackground forKey:@"reset"];

}