【问题标题】:Keyframe animation key time关键帧动画关键时间
【发布时间】:2023-03-04 22:06:01
【问题描述】:

我刚刚创建了一个这样的关键帧动画:

[UIView animateKeyframesWithDuration:10 delay:0 options:0 animations:^{
    [UIView addKeyframeWithRelativeStartTime:0 relativeDuration:.1 animations:^{
        view.alpha = 0;
    }];
} completion:nil];

这是一个被创建的CAKeyframeAnimation

(lldb) po [self.layer animationForKey:@"opacity"]
<CAKeyframeAnimation:0x10a6364b0; keyTimes = (
    0,
    "0.1",
    1
); values = (
    1,
    0,
    0
); calculationMode = linear; delegate = <UIViewKeyframeAnimationState: 0x10a6358d0>; fillMode = both; timingFunction = easeInEaseOut; duration = 10; keyPath = opacity>

问题:

整个动画应该需要 10 秒,不透明度动画需要 10 * 0.1 = 1 秒,对吧?当我查看动画时,变化的动画时间超过 1 秒。

为什么?

【问题讨论】:

  • 调试输出看起来是正确的(从 0 到 1 秒动画从 100% 到 0% 然后再用 9 秒从 0% 到 0% 动画)。你能描述一下你所看到的吗?你在其他地方改变不透明度吗?你没有在模拟器中开启慢动画吧?
  • 是的,CAKeyframeAnimation 看起来完全正确。我看到的是不透明度正在改变 2 - 2.5 秒,而不是一秒。我没有在任何地方更改它,并且慢速动画已关闭。
  • 如果您自己创建关键帧动画(而不是通过 UIView 方法),您会看到同样的情况吗?
  • @DavidRönnqvist 我还没试过那个。好主意。但是我在整个应用程序中使用CAKeyframeAnimation 来处理其他事情,它就像一个魅力。只是想试试这个新的UIView 东西和繁荣。

标签: ios cocoa-touch uiview ios7 core-animation


【解决方案1】:

原因是动画的计时函数不是线性的。

“时间和空间是相对的概念。” – 相对论

图层和动画使用分层计时系统,其中每个对象都有自己的本地时间,这取决于其父对象和自己的计时参数。

例如,动画具有定义其节奏的计时功能。 UIKit 创建的动画的默认计时函数是 ease-in ease-out 计时函数,它定义了一个缓慢开始的时间,在其持续时间的中间加速,然后在完成之前再次减速。它使流畅的动画不会突然开始或停止。但是,它也会调整关键帧动画的关键时间,这在您需要精确计时时很烦人。

您可以通过将UIViewAnimationOptionCurveLinear 选项传递给animateKeyframesWithDuration:delay:options:animations:completion: 方法来禁用缓入缓出时间。我不确定它是否是有意的,因为您需要将值从 UIViewAnimationOptions 转换为 UIViewKeyframeAnimationOptions 并且文档没有说明这一点。也许更好(但更冗长)的方法是将关键帧动画块嵌入到标准动画块中,如下所示:

[UIView animateWithDuration:10 delay:0 options:UIViewAnimationOptionCurveLinear animations:^{
    [UIView animateKeyframesWithDuration:0 /*inherited*/ delay:0 options:0 animations:^{
        [UIView addKeyframeWithRelativeStartTime:0 relativeDuration:.1 animations:^{
            view.alpha = 0;
        }];
    } completion:nil];
} completion:nil];

【讨论】:

  • 我花了两个小时想知道为什么这个 *$!§ 动画不是线性的,即使我通过 UIViewKeyframeAnimationOptionCalculationModeLinear(加上它的默认值)。先生救了我,谢谢。
  • 我偶然发现了这个答案。我自己多年来一直在这样做,它确实解决了这个问题,尽管我仍然无法通过在 KeyFrameAnimation 周围嵌入标准的UIView 动画来确切地找出为什么我需要以这种方式“破解”它。我知道它有效,但我的好奇心让我很痒:-) +1 进行分析。
  • @Nicolas 这似乎不再适用于 iOS 9。有什么选择吗?
  • @Xzya 在 iOS 9 上为我工作。
  • 好答案。我认为您也可以在animateKeyframesWithDuration options 中添加 UIViewAnimationOptionCurveLinear。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-12-22
  • 2017-05-30
  • 2021-03-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多