0

I'm trying to implement a nested animation block. The issue I'm facing is that only my completion block code is called. When I comment that out, the initial part is called. How do I get the animation to finish the first animation and then call the second one?

- (void)viewDidAppear:(BOOL)animated
{
    _finalLogoCenter = self.logoImage.center;
    // Logo Animation
    [self logoAnimation];
}

- (void) logoAnimation
{

    [UIView animateWithDuration:1.0
                          delay:0.0
                        options:UIViewAnimationOptionTransitionNone
                     animations:^ {
                         // Move Up
                         [self moveLogoUpFirst];
                     }completion:^(BOOL finished)
                    {
                         // Move below final point
                         [self moveLogoDownBeyondFinalPoint];
                    }];
}

- (void) moveLogoUpFirst
{
    __block CGPoint logoCenter = self.logoImage.center;
    logoCenter.y = 290.0f;
    self.logoImage.center = logoCenter;
    [self.logoImage setAlpha:0.0f];
    [UIView animateWithDuration:1.0
                          delay:0.0
                        options:UIViewAnimationOptionTransitionNone
                     animations:^ {
                         logoCenter.y = _finalLogoCenter.y - 20;
                         self.logoImage.center = logoCenter;
                         [self.logoImage setAlpha:1.0f];
                     }completion:nil];
}

- (void) moveLogoDownBeyondFinalPoint
{
    __block CGPoint logoCenter = self.logoImage.center;
    self.logoImage.center = logoCenter;
    [UIView animateWithDuration:1.0
                          delay:0.0
                        options:UIViewAnimationOptionTransitionNone
                     animations:^ {
                         logoCenter.y = _finalLogoCenter.y + 5;
                         self.logoImage.center = logoCenter;
                     }completion:nil];
}
Anil
  • 2,430
  • 3
  • 37
  • 55
  • try with performSelector waitUntilDone – Jasper Mar 27 '14 at 11:59
  • @JasperPol Thanks. That does work. But I need to calculate the time of the previous animation and set it here in afterDelay. Won't the completion block take care of that issue? – Anil Mar 27 '14 at 12:08
  • well, you know the animation takes 1 second, so the completion block is fired after 1 second. check this answer, it might be a better way of animating what you want to do: http://stackoverflow.com/questions/1632364/shake-visual-effect-on-iphone-not-shaking-the-device/10007898#10007898 – Jasper Mar 27 '14 at 12:14

2 Answers2

1

I believe the problem comes from an animation which is inside another animation. That does not make any sense and i guess it could lead to unexpected behavior.

What you could do is set a completion block in the first animation

- (void) moveLogoUpFirst:(void (^)(BOOL finished))completion
{
    __block CGPoint logoCenter = self.logoImage.center;
    logoCenter.y = 290.0f;
    self.logoImage.center = logoCenter;
    [self.logoImage setAlpha:0.0f];
    [UIView animateWithDuration:1.0
                          delay:0.0
                        options:UIViewAnimationOptionTransitionNone
                     animations:^ {
                         logoCenter.y = _finalLogoCenter.y - 20;
                         self.logoImage.center = logoCenter;
                         [self.logoImage setAlpha:1.0f];
                     }completion:^(BOOL finished)
                    {
                         completion(finished);
                    }];
}

And when you call it just use this code without any animation :

[self moveLogoUpFirst:^(BOOL finished) {
    [self moveLogoDownBeyondFinalPoint]
}];
streem
  • 9,044
  • 5
  • 30
  • 41
0

As a general approach, you can create a function like this:

-(void)someFunctionWithCompletion:(void (^)(void))completionBlock{
    [UIView animateWithDuration:1.0
                          delay:0.0
                        options:UIViewAnimationOptionTransitionNone
                     animations:^ {
                     }completion:^(BOOL finished)
                     {
                       if(completionBlock)
                          completionBlock();
                     }];
}

And call it:

[... someFunctionWithCompletion:^{
}];
Calin Chitu
  • 1,099
  • 7
  • 13