objective framework developer apple core-animation

core-animation - framework - swift ios documentation



animando múltiples CALayers, pero no en el mismo espacio de tiempo (5)

Todavía me gustaría escuchar sugerencias de otros, pero creo que he resuelto esto.

Ahora estoy creando objetos CAAnimation específicos y especificando su propiedad beginTime . Estaba haciendo esto antes y no funcionaba, lo que finalmente me di cuenta es que para que la propiedad beginTime sea ​​reconocida, la animación debe agregarse a CAAnimationGroup .

Por lo tanto, mi código se ve así:

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"]; }

Tengo varios CALayers que estoy tratando de animar a una nueva zPosition con cada capa un poco retrasada de las otras.

Cada animación debe tomar 0.25 segundos y comenzar 0.05 segundos después de que comenzó la animación anterior. Al final de cada animación, la capa se eliminará del árbol de capas.

He estado utilizando con éxito el método -animationDidStop:finished: delegate para eliminar mis capas cuando terminan, pero no he podido ordenar las animaciones correctamente.

¿Es posible programar animaciones de esta manera y cómo?


Gracias por compartir sus resultados, también descubrí que la propiedad BeginTime no funciona si se usa sin un grupo.

En mi caso, algunas de las configuraciones como BeginTime y Duration se ignoraron si se configuraron en CABasicAnimation, pero funcionaron si se configuraron directamente CAAnimationGroup.


Descubrí que la propiedad BeginTime sí funciona sin incluir las animaciones en un grupo si basas su valor como un delta del valor devuelto por la función CACurrentMediaTime () de QuartzCore.

por ejemplo anim.beginTime = CACurrentMediaTime() + 0.05;


Desearía tener el representante para comentar, pero la razón por la que la configuración de anim.beginTime a CACurrentMediaTime () funciona es revelada por algunos otros documentos:

AVCoreAnimationBeginTimeAtZero Utilice esta constante para configurar la animación de la animación de CoreAnimation como hora de tiempo 0. La constante es un valor positivo pequeño, distinto de cero, que impide que CoreAnimation reemplace 0.0 con CACurrentMediaTime. Disponible en iOS 4.0 y posterior. Declarado en AVAnimation.h.

Por lo tanto, la configuración normal de beginTime en 0 es una abreviatura para configurarlo en CACurrentMediaTime (). Entonces puedes usar el para escalonar el inicio de varios grupos.


Swift 3

Resulta que puedes hacer esto relativamente simple al hacer lo siguiente:

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 }

Todas las capas son CALayer o CAShapeLayer, y en caso de que se pregunte qué son ovalPathSmall y 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)