2009-02-18 76 views
8

我有幾個CALayers,我試圖動畫到一個新的zPosition每個層稍微延遲。動畫多個CALayers,但不在同一時間空間

每個動畫應該需要0.25秒,並在上一次動畫開始後0.05秒開始。在每個動畫結束時,圖層將從圖層樹中移除。

我已經成功地使用​​委託方法來刪除我的圖層,但我無法正確地對動畫進行排序。

是否有可能以這種方式安排動畫,以及如何?

回答

17

我還想聽聽其他人的建議,但我想我已經解決了這個問題。

我正在創建特定的CAAnimation對象並指定它們的beginTime屬性。我之前正在做這件事,並沒有奏效,我終於意識到,要讓beginTime屬性得到尊重,動畫必須被添加到CAAnimationGroup

所以,我的代碼如下所示:

NSArray *layers = /* layers to be animated away */ 
CGFloat startOffset = 0.01; 

for (NSInteger index = 0; index < layers.count; index++) { 
    CALayer *layer = [layers objectAtIndex:index]; 

    CABasicAnimation *zoomOut = [CABasicAnimation animationWithKeyPath:@"zPosition"]; 
    zoomOut.toValue = [NSNumber numberWithDouble:400.0]; 
    zoomOut.beginTime = index * startOffset; 

    CAAnimationGroup *group = [CAAnimationGroup animation]; 
    group.animations = [NSArray arrayWithObject:zoomOut]; 
    group.delegate = self; 

    [layer addAnimation:group forKey:@"zoomAway"]; 
} 
+0

我也一直在尋找高和低的答案,並嘗試了各種不同的事情。我認爲可以創建一個共享CAAnimationGroup,所有圖層都可以共享作爲參考時間幀,但這顯然不起作用。我現在認爲這可能是解決這個問題的方法,但也希望聽到更多的人瞭解這一點。 – Felixyz 2009-06-16 20:45:59

0

感謝您分享您的結果,我還發現,如果沒有一組使用的BeginTime屬性不起作用。

在我的情況下,如果在CABasicAnimation上設置BeginTime和Duration等一些設置,但是如果直接設置CAAnimationGroup則會被忽略。

14

我發現BeginTime屬性確實可以在沒有將動畫放入組中的情況下工作,如果您將它的值作爲QuartzCore的CACurrentMediaTime()函數返回的值的增量值。

例如anim.beginTime = CACurrentMediaTime() + 0.05;

+0

很酷。我不記得當初我做這件事時試圖這樣做。 – 2012-05-28 19:00:02

5

我希望我的代表發表評論,但該設置anim.beginTime到CACurrentMediaTime()的工作原理是通過一些其他的文檔透露了原因:

AVCoreAnimationBeginTimeAtZero 使用此常數設置CoreAnimation的動畫BEGINTIME財產時間爲0. 該常數是一個小的非零正值,它可以防止CoreAnimation用CACurrentMediaTime替換0.0。 Available in iOS 4.0及更高。 在AVAnimation.h中聲明。

因此,beginTime爲0的正常設置是將其設置爲CACurrentMediaTime()的簡寫。所以你可以用它來錯開各組的開始。

+0

「因此,beginTime爲0的正常設置是將其設置爲CACurrentMediaTime()的簡寫形式,哇,一直在尋找這個解釋的全部內容,非常感謝。 – langtutheky 2017-03-17 18:34:38

0

斯威夫特3

事實證明,你可以通過執行以下操作執行此操作相對簡單:

var timeOffset:Double = 0 
let delay:Double = 0.1 
for layer in layers { 
    let a = CABasicAnimation(keyPath: "path" 
    a.fromValue = layer.ovalPathSmall.cgPath 
    a.toValue = layer.ovalPathLarge.cgPath 
    a.fillMode = kCAFillModeForwards 
    a.beginTime = CACurrentMediaTime() + timeOffset 
    a.duration = 0.3 
    a.isRemovedOnCompletion = true 
    layer.add(a, forKey: nil) 

    timeOffset += 0.3 + delay 
} 

所有層的CALayer或CAShapeLayer,並且如果你想知道什麼ovalPathSmall和ovalPathLarge是:

ovalPathSmall = UIBezierPath(arcCenter: position, radius: smallRadius, startAngle: 0, endAngle: 2 * .pi, clockwise: true) 
ovalPathLarge = UIBezierPath(arcCenter: position, radius: largeRadius, startAngle: 0, endAngle: 2 * .pi, clockwise: true)