2013-12-11 227 views
7

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

[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

调试输出看起来是正确的(从0到1秒动画从100%到0%,那么为从0%到0%动画再过9秒)。你能描述你所看到的吗?你是否在其他地方改变了不透明度?你还没有在模拟器中打开慢动画,对吧? –

+0

是的,CAKeyframeAnimation看起来完全正确。我看到的是,不透明度正在改变2 - 2.5秒,而不是一个。我不会在任何地方改变它,并且慢动画关闭。 –

+1

如果您自己创建关键帧动画(不是通过UIView方法),您是否看到相同的东西? –

回答

8

原因是动画的定时功能不是线性的。

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

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

例如,动画具有定义其调步的定时功能。 UIKit创建的动画的默认定时功能是易入缓出定时功能,该功能定义缓慢开始,在整个持续时间中加速并在完成之前再次减速的时间。它使得流畅的动画不会突然启动或停止。然而,当你需要精确的时机时,它也会随着你的关键帧动画的关键时刻而变得烦人。

您可以通过将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]; 
+0

我通过了两个小时,想知道为什么这个* $!§动画不是线性的,即使我传递了'UIViewKeyframeAnimationOptionCalculationModeLinear'(加上它的默认值)。你先生救了我,谢谢。 – AncAinu

+0

我无意中偶然发现了这个答案。我自己多年来一直在做这件事,它确实解决了这个问题,但我仍然无法确切知道为什么我需要通过将标准的'UIView'动画嵌入到KeyFrameAnimation中来以这种方式“破解”它。它工作,我知道,但我的好奇心痒痒我:-) +1分析。 – Unheilig

+0

@Nicolas这似乎不再适用于iOS 9。任何选择? – Xzya