LodeRunner
LodeRunner

Reputation: 8393

UIView animations do not work when a delayed animation is added

I'm trying to move a UILabel twice but I'm getting strange behaviour. Here was my first animation:

- (IBAction)doAnimation:(id)sender
{
    CGRect labelFrame = self.label.frame;
    CGRect newFrame = CGRectMake((random() / (float)RAND_MAX) * self.view.frame.size.width,
                                 (random() / (float)RAND_MAX) * self.view.frame.size.height,
                                 labelFrame.size.width,
                                 labelFrame.size.height);
    [UIView animateWithDuration:2
                          delay:0
                        options:0
                     animations:^{
                         self.label.frame = newFrame;
                     }
                     completion:NULL];
}

This works perfectly. The label fades in while moving into place.

I then added a second delayed animation by adding this code at the end of doAnimation:

    CGRect newFrame2 = CGRectMake((random() / (float)RAND_MAX) * self.view.frame.size.width,
                          (random() / (float)RAND_MAX) * self.view.frame.size.height,
                          labelFrame.size.width,
                          labelFrame.size.height);
    [UIView animateWithDuration:2
                          delay:3
                        options:0
                     animations:^{
                         self.label.frame = newFrame2;
                     }
                     completion:NULL];

In this case, I get a different behaviour. The label jumps to the end of the first animation, waits the delay out, then animates the second move.

Out of curiosity, I tried animating two properties in animation 1.

animations:^{
                 self.label.frame = newFrame;
                 self.label.alpha = 1.0f;
             }

The alpha animates correctly, but the frame change doesn't.

If I add an alpha change in animation 2, then the alpha doesn't animate in animation 1 (instead just jumps to the end).

Is it possible to create an animation sequence on similar properties using delayed animations? I need to extend this to an arbitrary number of animations, depending on user inputs.

Upvotes: 2

Views: 1366

Answers (2)

LodeRunner
LodeRunner

Reputation: 8393

I found a solution for this. Here it is.

I added an array to save an arbitrary number of coordinates to point to.

@property (nonatomic, retain) NSMutableArray* animationCoordinates;

I then add views to the array before launching the animation sequence.

I also added a method to launch the next animation.

- (void)playNextAnimation
{
    if (self.animationCoordinates.count > 0)
    {
        CGPoint point = [[self.animationCoordinates objectAtIndex:0] CGPointValue];
        CGRect labelFrame = self.label.frame;
        CGRect newFrame = CGRectMake(point.x,
                                     point.y,
                                     self.originalHandFrame.size.width,
                                     self.originalHandFrame.size.height);
        [self animateWithDuration:2.0
                            delay:0.0
                       animations:^{
                           self.label.frame = newFrame;
                           self.label.alpha = 1.0f;
                       }
                       completion:^(BOOL success){
                           [self playNextAnimation];
                       }];
        [self.buttonsToAnimate removeObjectAtIndex:0];
    }
}

When I want to start my animations, I just call

[self playNextAnimation];

This plays the animations in sequence until all points have been visited.

Upvotes: 0

neeraj
neeraj

Reputation: 1221

performing this animation is an asynchronous thing, i.e., the command for animating is given, and the program flow continues.
Also, if animation command is given for a view when the previous command has not completed, the previous command is completed without any animation and the new animation is performed.

I think you should put the second animation code in the completion block of the first animation, for which you are passing NULL currently. completion gets executed AFTER the animation has been performed, and at that point you wish to start your second animation I think.

Upvotes: 0

Related Questions