3

这是一个有点棘手的搜索。不太确定要敲击谷歌或 SO,所以如果之前已经回答过这个问题,我深表歉意。

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

检测交互很容易,但能够确定动画何时结束一个循环并不容易。通过检测到这一点,我希望实现动画完成最后一个循环并停止的效果,而不是从看起来很不友好的屏幕上粗暴地删除它。

这就是我现在正在做的事情,但它不起作用

- (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当我期望它时,没有调用委托调用。显然我误解了文档。

4

1 回答 1

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"];

}
于 2013-09-08T23:31:27.387 回答