2009-02-18 11 views
8

Ho diversi CALayers che sto provando ad animare su un nuovo zPosition con ogni livello leggermente ritardato dagli altri.animare più CALayers, ma non nello stesso spazio di tempo

Ogni animazione dovrebbe richiedere 0,25 secondi e iniziare 0,05 secondi dopo l'animazione precedente avviata. Alla fine di ogni animazione il livello verrà rimosso dall'albero dei livelli.

Ho utilizzato con successo il metodo delegato -animationDidStop:finished: per rimuovere i miei livelli al loro completamento ma non sono stato in grado di ordinare correttamente le animazioni.

È possibile pianificare le animazioni in questo modo e in che modo?

risposta

17

Mi piacerebbe ancora sentire altri suggerimenti, ma penso di averlo risolto.

Sto creando ora specifici oggetti CAAnimation e specificando la loro proprietà beginTime. Lo stavo facendo prima e non funzionava, quello che ho finalmente capito è che per la proprietà beginTime da onorare l'animazione deve essere aggiunta a un CAAnimationGroup.

Quindi, il mio codice simile a questo:

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

Ho anche cercato in alto e in basso una risposta a questo e ho provato varie cose. Ho pensato che sarebbe stato possibile creare un CAAnimationGroup condiviso che tutti i livelli potessero condividere come un intervallo di tempo di riferimento, ma ovviamente non funziona. Ora penso che questo sia probabilmente il modo per farlo, ma mi piacerebbe anche sentire gli altri con maggiori informazioni in merito. – Felixyz

0

Grazie per la condivisione dei risultati, ho anche scoperto che la proprietà BeginTime non funziona se utilizzato senza un gruppo.

Nel mio caso, alcune impostazioni come BeginTime e Duration sono state ignorate se impostate su CABasicAnimation, ma hanno funzionato se impostate direttamente CAAnimationGroup.

14

Ho trovato che la proprietà BeginTime funziona effettivamente senza inserire le animazioni in un gruppo se si basa il valore come un delta dal valore restituito dalla funzione CACurrentMediaTime() di QuartzCore.

ad es. anim.beginTime = CACurrentMediaTime() + 0.05;

+0

cool. Non ricordo di averlo provato quando l'ho fatto in origine. –

5

Vorrei avere il rappresentante di commentare, ma la ragione che l'impostazione anim.beginTime a CACurrentMediaTime() funziona è rivelato da alcuni altri documenti:

AVCoreAnimationBeginTimeAtZero utilizzare questa costante per impostare l'animazione di proprietà BEGINTime del Core Animation essere il tempo 0. La costante è un valore piccolo, non zero, positivo che impedisce a CoreAnimation di sostituire 0.0 con CACurrentMediaTime. Disponibile in iOS 4.0 e versioni successive. dichiarato in AVAnimation.h.

Quindi l'impostazione normale di beginTime su 0 è una scorciatoia per l'impostazione su CACurrentMediaTime(). Quindi puoi usare per scaglionare l'inizio di vari gruppi.

+0

"Quindi l'impostazione normale di beginTime su 0 è una scorciatoia per impostarla su CACurrentMediaTime()", wow, ho cercato dappertutto questa spiegazione, grazie mille. – langtutheky

0

Swift 3

scopre che può fare questo relativamente semplicemente facendo le seguenti:

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 
} 

Tutti gli strati sono CALayer o CAShapeLayer, e nel caso in cui ti stai chiedendo cosa ovalPathSmall e ovalPathLarge sono:

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) 
Problemi correlati