Detener la llamada de -removeAllAnimaitions

Actualmente, en la plataforma iOS, cuando se presiona el button de inicio, se envía -removeAllAnimations a la propiedad de layer cada vista.

¡Necesito desesperadamente detener este comportamiento!

Actualmente estoy usando una CABasicAnimation que anima el dibujo de un círculo para que actúe como un timer.

Aquí hay un gif del process. El timer comienza y la animation comienza suavemente (perdón los pobres fps). Una vez que se presiona el button de inicio y regrese a la aplicación, la animation termina inmediatamente.

Estoy usando el - (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag method para detectar cuándo se detiene el timer. Todo esto está funcionando muy bien, hasta que presiono el button de inicio.

Al presionar el button de inicio, se completa inmediatamente la animation y se completa prematuramente el timer.

¿Hay alguna forma de detener este comportamiento, como un método en UIViewController o alguna propiedad que puedo establecer en el .plist de mi proyecto?

Aquí está la fuente de mi primera statement. CABasicAnimation desaparece cuando se presiona el button de inicio

Aquí están mis bashs actuales para resolver el problema.

  1. Subclass CALayer para anular -removeAllAnimations con la esperanza de evitar la detención de la animation.
  2. Método realizado swizzling en el método +load en una extensión de la class CALayer que swizzles -removeAllAnimations a algún método falso. He determinado que se está llamando al método falso, pero aún se está experimentando el mismo comportamiento.

Creo un ejemplo para animar la position de un CALayer usando CABasicAnimation .

La idea es almacenar algún context de la animation cuando la aplicación pasa a segundo plano y restaurar la animation cuando la aplicación regresa.

 @interface ViewController () { BOOL animationStoped ; CFTimeInterval time ; CGPoint position ; } @property (nonatomic, strong) UIView *viewAnimate ; @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; _viewAnimate = [[UIView alloc] initWithFrame:CGRectMake(0.0, 100.0, 100.0, 100.0)] ; _viewAnimate.backgroundColor = [UIColor networkingColor] ; [self.view addSubview:_viewAnimate] ; CABasicAnimation *animation = [self animation] ; [_viewAnimate.layer addAnimation:animation forKey:@"animation.position"] ; _viewAnimate.layer.position = CGPointMake(250.0, 350.0) ; time = [_viewAnimate.layer convertTime:CACurrentMediaTime() fromLayer:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleEnterBackgroundNotification:) name:UIApplicationDidEnterBackgroundNotification object:nil] ; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleDidBecomeActiveNotification:) name:UIApplicationDidBecomeActiveNotification object:nil] ; } - (CABasicAnimation *)animation { CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"position"] ; animation.fromValue = [NSValue valueWithCGPoint:CGPointMake(50.0, 50.0)] ; animation.toValue = [NSValue valueWithCGPoint:CGPointMake(250.0, 350.0)] ; animation.duration = 5.0 ; animation.delegate = self ; return animation ; } - (void)handleEnterBackgroundNotification:(id)nty { CAAnimation *aa = [_viewAnimate.layer animationForKey:@"animation.position"] ; animationStoped = aa != nil ; if (animationStoped) { CALayer *presentationLayer = _viewAnimate.layer.presentationLayer ; position = presentationLayer.position ; CFTimeInterval now = [_viewAnimate.layer convertTime:CACurrentMediaTime() fromLayer:nil]; time = now - time ; } } - (void)handleDidBecomeActiveNotification:(id)nty { if (animationStoped) { CABasicAnimation *animation = [self animation] ; animation.fromValue = [NSValue valueWithCGPoint:position] ; animation.duration -= time ; [_viewAnimate.layer addAnimation:animation forKey:@"animation.position"] ; } } 

Primero, quiero agradecer a @KudoCC por la respuesta.

Si bien la solución dada podría funcionar, he encontrado una forma más fácil con la propiedad -[CAAnimation removedOnCompletion] .

 CAAnimation * anim = ...; anim.removedOnCompletion = NO; // anim will now continue after home button press 

Esta solución parece anular las llamadas pnetworkingeterminadas de -[CALayer removeAllAnimations] emitidas por el sistema operativo cuando se presiona el button de inicio.