I'm simply closing doors, delaying 2 sec/calling a method then opening them back. One comes from the left side and the other from the right side. I first used UIView animation block but then realized whenever user leaves the app during animation, its completion block would never get called.
I could not find anyone complaining about such behavior when interruption happens during animation thus could not solve the problem and now I'm hoping CAAnimation's animationDidStop or CATransaction's completion block will get called no matter what 100%.
EDIT
Tried below code and it worked even though I couldn't make the delay work. (CACurrentMediaTime()+delay makes the second animation end immediately) Most importantly, I'm happy that animationDidStop ALWAYS gets called even if animation is interrupted. (Block-based UIView animations' completion blocks never get called if user leaves the app OR a VC's animation is fired at the same time) I would love to know why this happens with UIView animations and if there's a solution to this.
Should I stick with this method and try to fix the delay or come up with some other approach? CAAnimationGroup doesn't work in this case because animationDidStop gets called when the whole group is finished hence can't call methods when the first animation is ended.
-(void)action { CABasicAnimation *animDoorLeftClose = [CABasicAnimation animationWithKeyPath:@"position.x"]; animDoorLeftClose.fromValue = [NSNumber numberWithFloat:self.doorLeft0.position.x]; animDoorLeftClose.toValue = [NSNumber numberWithFloat:self.doorLeft0.position.x + self.frame.size.width/2]; animDoorLeftClose.duration = 0.2; animDoorLeftClose.beginTime = 0.0; self.doorLeft0.position = CGPointMake(self.doorLeft0.position.x + self.frame.size.width/2, self.doorLeft0.position.y); [self.doorLeft0 addAnimation:animDoorLeftClose forKey:@"leftClosing"]; CABasicAnimation *animDoorRightClose = [CABasicAnimation animationWithKeyPath:@"position.x"]; [animDoorRightClose setValue:@"doorClosing" forKey:@"id"]; animDoorRightClose.fromValue = [NSNumber numberWithFloat:self.doorRight0.position.x]; animDoorRightClose.toValue = [NSNumber numberWithFloat:self.doorRight0.position.x - self.frame.size.width/2]; animDoorRightClose.duration = 0.2; animDoorRightClose.beginTime = 0.0; animDoorRightClose.delegate = self; self.doorRight0.position = CGPointMake(self.doorRight0.position.x - self.frame.size.width/2, self.doorRight0.position.y); [self.doorRight0 addAnimation:animDoorRightClose forKey:@"rightClosing"]; } -(void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag { if([[anim valueForKey:@"id"] isEqual:@"doorClosing"]) { [self.delegate shipTOmap]; } [self doorClosed]; } else if ([[anim valueForKey:@"id"] isEqual:@"doorOpening"]) { [self doorOpened]; }} -(void)doorClosed { CABasicAnimation *animDoorLeftOpen = [CABasicAnimation animationWithKeyPath:@"position.x"]; animDoorLeftOpen.fromValue = [NSNumber numberWithFloat:[self.doorLeft0.presentationLayer position].x]; animDoorLeftOpen.toValue = [NSNumber numberWithFloat:[self.doorLeft0.presentationLayer position].x - self.frame.size.width/2]; animDoorLeftOpen.duration = 0.4; animDoorLeftOpen.beginTime = CACurrentMediaTime()+0.2; self.doorLeft0.position = CGPointMake([self.doorLeft0.presentationLayer position].x - self.frame.size.width/2, self.doorLeft0.position.y); [self.doorLeft0 addAnimation:animDoorLeftOpen forKey:@"leftOpening"]; CABasicAnimation *animDoorRightOpen = [CABasicAnimation animationWithKeyPath:@"position.x"]; [animDoorRightOpen setValue:@"doorOpening" forKey:@"id"]; animDoorRightOpen.fromValue = [NSNumber numberWithFloat:[self.doorRight0.presentationLayer position].x]; animDoorRightOpen.toValue = [NSNumber numberWithFloat:[self.doorRight0.presentationLayer position].x + self.frame.size.width/2]; animDoorRightOpen.duration = 0.4; animDoorRightOpen.beginTime = CACurrentMediaTime()+0.2; animDoorRightOpen.delegate = self; self.doorRight0.position = CGPointMake([self.doorRight0.presentationLayer position].x + self.frame.size.width/2, self.doorRight0.position.y); [self.doorRight0 addAnimation:animDoorRightOpen forKey:@"rightOpening"]; }