【问题标题】:iOS Time Variant AnimationiOS 时变动画
【发布时间】:2012-07-17 18:48:52
【问题描述】:

我有兴趣为视图制作类似抖动的动画,类似于

ios-icon-jiggle-algorithmerror-in-button-jiggle-algorithm

但是,这些解决方案实现了时不变动画,这意味着动画序列在动画开始之前是固定的,并且一遍又一遍地执行完全相同的动画。在这些情况下,旋转角度是预先计算好的。

我想做的是时变动画,其中动画随时间变化。在前面的示例中,我希望旋转角度根据一些基于时间的函数而变化。

打个比方,假设我正在为一块果冻制作动画。在动画开始时,我敲了一次果冻,它开始摇晃,然后随着时间的推移,摇晃的幅度逐渐减小,直到它完全不摇晃。

据我了解,我无法将随时间变化的值注入到动画块中,我认为唯一可行的做法是按照ios-multiple-animation-blocks 将固定动画字符串链接在一起。将 3 或 4 块递减动画值串在一起,我应该会得到一个可以接受的效果。

那么,如果有办法用 UIView 动画做我想做的事?还是我应该采用另一种方法?

[编辑]

为了更清楚我所说的时变的意思,我希望能够将动画属性的值指定为函数时间,而不必先验地预先计算动画属性。并且以一种(可能)允许我即时修改功能的方式这样做。作为一个具体的例子,我可能想要一个函数 f(t) 使得:

For t<0 f(t) = 0
For t>0 and t<1 f(t) = 1-t
For t>1 f(t)= 0

实际上,更好的 f(t) 表示形式如下:

f(t) = A(t)sin(????t)

[编辑#2]

经过一番考虑,我决定虽然理想情况下能够指定随时间变化的视图动画是我想要做的效果,但实际上,当它应用在应用程序中时,用户可能不会注意到我的编程能力。所以我只是要伪造它并使用预先计算并多次触发的关键帧动画。

【问题讨论】:

    标签: ios time uiviewanimation varying


    【解决方案1】:

    抱歉,如果不通过触发完成块中的下一个将多个动画链接在一起,您就无法使用 UIView 动画执行此操作,您真的不应该这样做。

    不过别担心,你要做的并不难。

    Core Animation 支持key-frame animations 属性,您可以在其中指定属性应在其间进行动画处理的值数组。您还可以指定属性从中读取其值的路径。

    如果您指定一个值数组,您可以细粒度地控制值之间的时间以及如何完成插值(指定值之间的计算)。

    你像这样创建一个新动画

    CAKeyframeAnimation *myJiggleAnimation = [CAKeyframeAnimation animationWithKeyPath:nameOfPropertyBeingAnimated];
    // example key paths could be @"position" or @"transform"
    [myJiggleAnimation setValues:[NSArray arrayWithValues:/* your values here */]];
    

    由于您将对象添加到 NSArray,因此它们必须包含在对象中。对于数字,这意味着使用NSNumbers。对于这种点、矩形或变换,有一个名为 NSValue 的类可以包装这些,就像这样

    [NSValue valueWithCGPoint:myPoint]; 
    [NSValue valueWithCGSize:mySize];
    [NSValue valueWithCGRect:myRect]; 
    [NSValue valueWithCATransform3D:myTransform]; // 3D transform
    [NSValue valueWithCGAffineTransform:myAffineTransform]; // 2D transform 
    

    然后要运行动画,请将其添加到应该动画的视图层中,像这样

    [[myView layer] addAnimation:myJiggleAnimation forKey:@"jiggle"];
    // The key is used so that you can reference the animation if you have to
    

    请注意,在动画结束时,动画属性的值不会改变,因此视图可能会跳回其原始状态。这是预期的行为。要让它以另一个值结束,只需在将动画添加到图层后将属性设置为其结束值即可。


    注意:由于它是核心动画,您必须将 QuartzCore.framework 导入您的项目并将 &lt;QuartzCore/QuartzCore.h&gt; 包含到您的代码中。

    【讨论】:

    • 我知道关键帧动画,但这似乎仍然让我不得不在开始动画之前预先计算动画值。是的,我可以更好地控制插值的发生方式,但它似乎仍然是固定值的插值,而不是随时间变化的值。以关键帧动画为例,我想将值指定为 values = f(t),它们是时间 t 的每个“动画周期”的计算机,其中 f(t) 本身随时间变化。
    • 没有内置动画支持(据我所知)。也许你可以继承 CAPropertyAnimation 并自己做(或者可能是子类 CAValueFunction (进行插值的类)并将其用作基本动画的插值。不过我还没有尝试过这些东西,所以我不确定是否他们真的很难做到,或者甚至可以工作。
    • 是的 .. 我想我是标准动画的 SOL,并且对这些标准类进行子类化对于我想做的事情来说似乎有点太多了。我可以使用 OpenGL 解决方案实现我想要的,但这对于这个应用程序来说太过分了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多