2009-02-18 16 views
8

Mam kilka CALayers, które próbuję animować do nowego zPosition z każdą warstwą nieco opóźnioną od pozostałych.animacja wielu obiektów CALayers, ale nie w tej samej przestrzeni czasu

Każda animacja powinna zająć 0,25 sekundy i rozpocząć się 0,05 sekundy po rozpoczęciu poprzedniej animacji. Na końcu każdej animacji warstwa zostanie usunięta z drzewa warstw.

Z powodzeniem używam metody delegatów -animationDidStop:finished: do usuwania moich warstw po ich zakończeniu, ale nie udało mi się prawidłowo zamówić animacji.

Czy można zaplanować animacje w ten sposób i jak?

Odpowiedz

17

Nadal chciałbym usłyszeć inne sugestie, ale myślę, że to rozwiązałem.

Teraz utworzę określone obiekty CAAnimation i określam ich właściwość beginTime. Robiłem to wcześniej i to nie działało, w końcu zdałem sobie sprawę, że dla własności beginTime należy dodać animację do CAAnimationGroup.

Więc mój kod wygląda następująco:

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

Ja również szukałem odpowiedzi na to pytanie i próbowałem różnych rzeczy. Sądziłem, że będzie można utworzyć jedną wspólną grupę CAAnimationGroup, którą wszystkie warstwy mogą udostępniać jako ramy czasowe, ale to oczywiście nie działa. Teraz myślę, że jest to prawdopodobnie sposób, aby to osiągnąć, ale chciałbym również usłyszeć od innych z lepszym wglądem w to. – Felixyz

0

Dziękujemy za udostępnienie wyników, ja również okazało się, że nieruchomość begintime nie działa, jeżeli są stosowane bez grupy.

W moim przypadku niektóre ustawienia, takie jak BeginTime i Duration były ignorowane, jeśli ustawione na CABasicAnimation, ale działały, jeśli ustawione bezpośrednio CAAnimationGroup.

14

Odkryłem, że właściwość BeginTime rzeczywiście działa bez umieszczania animacji w grupie, jeśli oparliście ją na wartości delta od wartości zwróconej przez funkcję CACurrentMediaTime() QuartzCore.

np. anim.beginTime = CACurrentMediaTime() + 0.05;

+0

fajne. Nie pamiętam, jak próbowałem, kiedy robiłem to pierwotnie. –

5

Chciałbym rep do komentarza, ale powodem, że ustawienie anim.beginTime do CACurrentMediaTime() działa objawia się przez niektórych innych dokumentów:

AVCoreAnimationBeginTimeAtZero Użyj tej stałej aby ustawić właściwości animacji na CoreAnimation za begintime na czas 0. Stała jest małą, niezerową wartością dodatnią, która uniemożliwia zastąpieniu CoreAnimation 0.0 CACurrentMediaTime. Dostępne w iOS 4.0 i nowszych wersjach. Zadeklarowane w AVAnimation.h.

Zatem normalne ustawienie beginTime na 0 jest skrótem dla ustawienia go na CACurrentMediaTime(). Możesz więc użyć do rozłożenia początków różnych grup.

+0

"Więc normalne ustawienie beginTime na 0 jest skrótem dla ustawienia go na CACurrentMediaTime()", wow, szukałem wszędzie tego wyjaśnienia, dziękuję bardzo. – langtutheky

0

Swift 3

Okazuje się, że można to zrobić w stosunkowo prosty sposób, wykonując następujące czynności:

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 
} 

Wszystkie warstwy są CALayer lub CAShapeLayer, aw przypadku, gdy zastanawiasz się co ovalPathSmall i ovalPathLarge są:

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) 
Powiązane problemy