¿Cómo animas las subcapas de la capa de una UIView durante una animation de UIView?

En una animation UIView para una vista, puede animar que se subasten sus subidas incluyendo UIViewAnimationOptionLayoutSubviews en el parámetro de opciones de [UIView animateWithDuration:delay:options:animations:completion:] . Sin embargo, no puedo encontrar una forma de animarla distribuyendo sus subcapas cuando no son capas de respaldo de algunas vistas; simplemente saltarían en su lugar para que coincida con los nuevos límites de la vista. Puesto que estoy trabajando con capas y no con vistas, parece que tengo que usar Core Animation en lugar de animation UIView, pero no sé cómo hacerlo (y cuándo) para que la animation de capa coincida con la vista animation.

Esa es mi pregunta básica. Lee más si quieres saber lo concreto que estoy tratando de lograr.

He creado una vista con un borde de puntos al agregar un CAShapeLayer a la capa de la vista (ver esta pregunta de superposition: borde de línea discontinua alnetworkingedor de UIView ). Ajuste la ruta del CAShapeLayer para que coincida con los límites de la vista en layoutSubviews .

Esto funciona, pero hay un problema cosmético: cuando los límites de la vista se animan en una animation UIView (como durante la rotation), el borde punteado salta a los nuevos límites de la vista en lugar de animarla suavemente a medida que la vista anima sus límites. Es decir, las partes derecha e inferior del borde punteado no se mantienen abrazadas a las partes derecha e inferior de la vista mientras la vista se anima. ¿Cómo puedo get el borde de puntos del CAShapeLayer para animar junto a la vista mientras anima sus límites?

Lo que estoy haciendo hasta ahora es adjuntar una CABasicAnimation a CAShapeLayer:

 - (void)layoutSubviews { [super layoutSubviews]; self.borderLayer.path = [UIBezierPath bezierPathWithRect:self.bounds].CGPath; self.borderLayer.frame = self.bounds; CABasicAnimation *pathAnimation = [CABasicAnimation animationWithKeyPath:@"path"]; [self.borderLayer addAnimation:pathAnimation forKey:nil]; } 

Esto hace que el borde punteado se anime, pero no tiene la function de temporización correcta y la duración de la animation para que coincida con la animation de la vista. Además, a veces, no queremos que el borde punteado se anime como, cuando la vista primero hace el layout, el borde no debe animarse desde una ruta antigua a la nueva ruta correcta; solo debería aparecer

Puede que ya hayas encontrado la respuesta, pero también he tenido problemas similares recientemente, ya que lo resolví, publicaré la respuesta.

En el método - layoutSubViews , puede get la animation UIView actual como CAAnimation la capa de CAAnimation con - animationForKey: method. Utilizando esto, puede implementar - layoutSubviews como:

 - (void)layoutSubviews { [super layoutSubviews]; // get current animation for bounds CAAnimation *anim = [self.layer animationForKey:@"bounds"]; [CATransaction begin]; if(anim) { // animating, apply same duration and timing function. [CATransaction setAnimationDuration:anim.duration]; [CATransaction setAnimationTimingFunction:anim.timingFunction]; CABasicAnimation *pathAnimation = [CABasicAnimation animationWithKeyPath:@"path"]; [self.borderLayer addAnimation:pathAnimation forKey:@"path"]; } else { // not animating, we should disable implicit animations. [CATransaction disableActions]; } self.borderLayer.path = [UIBezierPath bezierPathWithRect:self.bounds].CGPath; self.borderLayer.frame = self.bounds; [CATransaction commit]; }