如何将图层设置为意外结束动画的最终状态

Posted

技术标签:

【中文标题】如何将图层设置为意外结束动画的最终状态【英文标题】:How to set layer to the final state of an unexpectedly ended animation 【发布时间】:2014-01-06 23:49:23 【问题描述】:

我使用以下代码来旋转图像:

    CABasicAnimation *rotationAnimation;
    rotationAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];
    rotationAnimation.toValue = [NSNumber numberWithFloat: M_PI * 2.0 /* full rotation*/ * 1];
    rotationAnimation.duration = 1;    // this results in a speed of one full rotation per second
    rotationAnimation.cumulative = YES;
    rotationAnimation.repeatCount = 100;
    rotationAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];

    [self.imageView.layer addAnimation:rotationAnimation forKeyPath:@"rotationAnimation"];

当动画正常结束时,旋转100次后,动画结束与动画开始匹配,所以我不必担心presentationLayer匹配图层(可能会导致回弹效果)。

但是,如果我结束这个操作,使用:

    [self.imageView.layer removeAnimationForKey:@"rotationAnimation"];

当用户点击停止按钮时这是可能的,我需要将presentationLayer与图层匹配,否则我会恢复到原始状态。

我试过了:

    id value = [((CALayer *)self.imageView.layer.presentationLayer) valueForKeyPath:@"transform.rotation.z"];
    [self.imageView.layer setValue:value forKey:@"transform.rotation.z"];

没有工作(似乎没有做任何事情),并且:

    self.imageView.layer.transform = ((CALayer *)self.imageView.layer.presentationLayer).transform;

也不起作用(我在 45° XY 轴周围出现了奇怪的扭曲)。

我不确定还可以尝试什么。过去,当我不得不做类似的事情时,我只需要匹配presentationLayer的位置,或大小或......,但我从来不需要匹配它的旋转位置。

谢谢。

【问题讨论】:

【参考方案1】:

虽然这不是我正在寻找的答案,但这是我目前的解决方法。我仍然希望有人有更好的方法(并将分享:-)。

如果我不能将当前层设置到与presentationLayer相同的位置,那么我将在让它运行单个旋转的剩余部分后停止动画,因此它最终与层看起来像:

- (void) runSpinAnimation:(BOOL) run;


    id value = [((CALayer *)self.imageView.layer.presentationLayer) valueForKeyPath:@"transform.rotation.z"];
    CABasicAnimation *rotationAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];
    [self.imageView.layer removeAnimationForKey:@"rotationAnimation"];

    if (run) 
        rotationAnimation.toValue = [NSNumber numberWithFloat: M_PI * 2.0 /* full rotation*/ * 1];
        rotationAnimation.duration = 1;
        rotationAnimation.cumulative = YES;
        rotationAnimation.repeatCount = MAXFLOAT;
        rotationAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];

        [self.imageView.layer addAnimation:rotationAnimation forKey:@"rotationAnimation"];
    
    else 
        float radians = ((NSNumber *)value).floatValue;
        if (radians < 0)
            radians = M_PI + radians;
        rotationAnimation.fromValue = @(radians);
        rotationAnimation.toValue = [NSNumber numberWithFloat: M_PI * 1.0 /* full rotation*/ * 1];
        rotationAnimation.duration = 0.25;
        rotationAnimation.cumulative = YES;
        rotationAnimation.repeatCount = 1;
        rotationAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];

        [self.imageView.layer addAnimation:rotationAnimation forKey:@"rotationAnimation"];

    


【讨论】:

以上是关于如何将图层设置为意外结束动画的最终状态的主要内容,如果未能解决你的问题,请参考以下文章

如何从核心动画对象中引用图层?

选择性地覆盖 CALayer 隐式动画

如何将图块添加到谷歌地图并为其设置动画,即不断用新图块替换它们

在 CSS3 动画结束时保持最终状态

android循环属性动画结束后状态怎样变回原状态

复合图层(硬件加速)