确定动画周期的结束

3
这个有点棘手,不太确定该在Google或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没有在我预期的时候被调用。显然,我误解了文档。

我认为你想要使用animationDidEnd而不是animationDidStop。 - rdelmar
我认为这个方法不存在。至少它不是CAAnimationDelegate协议的一部分。你知道在哪里可以找到它吗? - tomasbasham
1个回答

2

好的,如果使用委托方法无法实现这一目标,我会通过搜索苹果的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"];

}

你应该将自己的答案标记为正确答案,以备将来参考。 - micantox

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接