如何在动画 CABasicAnimation 时改变速度

Posted

技术标签:

【中文标题】如何在动画 CABasicAnimation 时改变速度【英文标题】:How to Change Speed while Animation CABasicAnimation 【发布时间】:2012-06-26 10:29:33 【问题描述】:

在我的应用程序中,我使用 CABasicAnimation 制作动画。我想动态改变动画的速度,所以我添加了一个滑块来改变速度。以下是我的动画代码。但是我无法改变速度,当我改变速度的值时没有任何反应。

        CABasicAnimation * a = [CABasicAnimation animationWithKeyPath:@"position"];
    [a setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear]];

    CGPoint startPt = CGPointMake(self.view.bounds.size.width + displayLabel.bounds.size.width / 2,
                                  displayLabel.frame.origin.y);
    CGPoint endPt = CGPointMake(displayLabel.bounds.size.width / -2, displayLabel.frame.origin.y);

    [a setFromValue:[NSValue valueWithCGPoint:startPt]];
    [a setToValue:[NSValue valueWithCGPoint:endPt]];
    [a setAutoreverses:NO];
    [a setDuration:speeds];
    [a setRepeatCount:HUGE_VAL];
    [displayLabel.layer addAnimation:a forKey:@"rotationAnimation"];


    - (IBAction)speedSlider:(id)sender 

         speeds = slider.value;

   

【问题讨论】:

Change duration (speed) on a running animation的可能重复 2017 年的完整解决方案 ...***.com/a/45787919/294884,唷 【参考方案1】:

我认为改变速度的最好方法是改变你层的时间系统

displayLabel.layer.timeOffset =
     [displayLabel.layer convertTime:CACurrentMediaTime() fromLayer:nil]; 
displayLabel.layer.beginTime = CACurrentMediaTime(); 
displayLabel.layer.speed= slider.value;

您可以提前看到这一点。 https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/CoreAnimation_guide/AdvancedAnimationTricks/AdvancedAnimationTricks.html#//apple_ref/doc/uid/TP40004514-CH8-SW2

【讨论】:

@Fattie - 可能您正在寻找不同的东西。这是问题的准确和精确的答案。它非常适合我。 我明白你的意思@LesNie - 是的,它会在某些情况下提供解决方案。然而,它改变了整个层的时间尺度。需要更改正在运行的动画的属性是一个常见问题(在 ios 中非常困难)。我确实在您的回答上点击了“+1” :) 新年快乐!【参考方案2】:

编辑:看起来你会有更多的问题,不过:它不会look like 你可以在运行动画上更改类似的值。您必须删除当前动画并添加一个具有更改值的新动画。当您添加新动画时,这可能需要小心以防止产生不和谐的效果。

从上面的线程中,您可以通过不重复动画来做到这一点,而是使用委托 (see here) 继续重新添加动画,并为下一个动画循环设置新速度.

原帖:

您正在更改最初传递给动画的值。这不会影响正在运行的动画。您需要获取对它的引用,并更改动画对象的持续时间属性。在你的操作方法中是这样的:

CABasicAnimation *a = [displayLabel.layer animationForKey:@"rotationAnimation"];
a.duration = slider.value;

【讨论】:

我已经对其进行了更多研究,但您无法更改正在运行的动画的值。查看我的编辑 这就是你如何在 iOS 中制作可重新启动的动画 .. ***.com/a/45787919/294884【参考方案3】:

我认为 jrturton 是正确的,您不能更改已经运行的动画的属性。但是你可以做的是将动画分成几个小段,并在滑块值发生变化时改变下一段的速度。

动画不是从 A 点到 D 点,而是从 A-B、B-C、C-D 开始。使用父类的animationDidStop检查当前点,检查滑块值,启动下一个动画。

这可能会产生不平稳的运动,但如果您使用非常小的片段,您也许可以将其平滑。

【讨论】:

【参考方案4】:

你应该停止动画并以新的持续时间重新开始一个新的动画

但记得记录下 fromValue 和 toValue ,并使用旧的 toValue 作为新的 fromValue 来执行无缝更改

【讨论】:

【参考方案5】:

根据需要设置速度。

    a.duration=0.5;

试试这个...

【讨论】:

我想要基于滑块值的动态速度。动画对于静态值完全没问题【参考方案6】:

如果你只想要自动滚动文本,那么你也可以使用一个类

http://blog.stormyprods.com/2009/10/simple-scrolling-uilabel-for-iphone.html

它也可能适用于你的情况,试试吧。

【讨论】:

以上是关于如何在动画 CABasicAnimation 时改变速度的主要内容,如果未能解决你的问题,请参考以下文章

如何在动画开启时更改 CABasicAnimation 的 toValue/fromValue

当 CABasicAnimation 正在制作动画时,我该如何回调?

CABasicAnimation 在动画完成后重置为初始值

如何使用 CABasicAnimation 从一个点移动到另一个点?

如何正确设置 CABasicAnimation(开始)时间?

在任何时间点获取 CABasicAnimation 中扩展圆圈的大小