如何使用 CFTimeInterval 为动画指定 beginTime?

Posted

技术标签:

【中文标题】如何使用 CFTimeInterval 为动画指定 beginTime?【英文标题】:How to specify an beginTime for an animation by using CFTimeInterval? 【发布时间】:2009-07-22 16:09:54 【问题描述】:

就我的理解而言,beginTime 可以用来表示“嘿,正好在 12:00 点开始”。但是我如何用 CFTimeInterval 类型来说明这一点?我以为这无非是一种“浮点”值来指定秒数。

或者与 CAMediaTiming 协议中指定的 timeOffset 属性有何不同?

【问题讨论】:

【参考方案1】:

我在文档中错过的内容:beginTime 位于“核心动画绝对时间”中,因此您必须获取当前时间并指定您的偏移量:

// Start in 5 seconds
theAnimation.beginTime = CACurrentMediaTime() + 5;

【讨论】:

beginTime 在父时间空间中指定,而不是相对于绝对时间。 @an0,显然,就我而言,父时间空间与 CACurrentMediaTime() 相同,所以它工作得很好。你会如何引用父时间空间? 我们应该以图层时间空间中的当前时间——直接添加到图层的动画的父时间空间——为基础。如果图层的 beginTime 设置为非零,您的代码将无法工作。详情见我的回答。【参考方案2】:

你首先需要像这样转换到图层的时间空间

let currentLayerTime = myLayer.convertTime(CACurrentMediaTime(), from: nil)

然后您可以将beginTime 设置为相对于图层的现在时间。例如,让动画在 2 秒内开始:

myAnimation.beginTime = currentLayerTime + 2

您可能还希望将fillMode 设置为.backwards,以便在添加动画之前设置最终属性值:

myAnimation.fillMode = .backwards
myLayer.someProperty = someFinalValue
myLayer.addAnimation(myAnimation, forKey: "myAnimationName")

【讨论】:

太棒了,let currentLayerTime = myLayer.convertTime(CACurrentMediaTime(), from: nil) 如此重要,因为CACurrentMediaTime() 可能不那么精确【参考方案3】:

不,这不是 beginTime 所做的。它指定其父动画的相对开始时间(默认情况下,组中的多个动画同时触发)。

来自documentation:

指定开始时间 接收者与其父母的关系 对象(如果适用)。

timeOffset 导致它在将在 offSet 时间所在的帧处开始动画,当它到达结尾时,它会循环播放。换句话说,假设 A、B、C、D、E 是动画帧,如果您将 beginTime 或 timeOffset 设置为正常情况下点击帧 C 时的值,则会在各种情况下发生这种情况。

Normal      |A->B->C->D->E
beginTime:  |      A->B->C->D->E
timeOffset: |C->D->E->A->B

【讨论】:

只设置timeOffset不会延迟动画和改变初始时间。你的'timeOffset'行真的是你设置'timeOffset'和'beginTime'会发生什么......对吗? Louis,你知道是否有办法只运行动画,如:部分:| - - A->B->C,所以与你提到的 beginTime 情况基本相同,但它在到达结束时停止而不是让它循环? 像@LouisGerbarg 一样工作。谢谢【参考方案4】:

我认为 CAMediaTiming 协议的文档非常糟糕。 Time Warp in Animation 是对 CAMediaTiming 协议所有属性的详尽解释(重新文档化)。

【讨论】:

以上是关于如何使用 CFTimeInterval 为动画指定 beginTime?的主要内容,如果未能解决你的问题,请参考以下文章

圆形到矩形的变换动画

平滑地加速正在运行的旋转动画

UIView Swift 倾斜动画

如何让jquery动画效果在屏幕滚动到指定位置才执行

动画视图 - 旋转、缩小和移出屏幕

如何使用曲线为 NSView 设置动画