objective-c: executing multiple transitionWithView animation blocks
Asked Answered
R

2

5

I'm trying to make a simple Simon game (an increasing sequence of colors flash and the user has to try to repeat that sequence). The way I'm going about it is by having 4 UIViews with 8 images. So there's a UIView for red, blue, green, and yellow. And I have gifs of dark green, light green, dark red, light red, etc.

So in my code, I'm using UIView's transitionWithView animation block: The UIView imageView.image is defaulted to the dark color image and this block is transitioning to light colored image, and on completion going back to the dark color image (to give it a "lighting up" look).

- (void) animateColor:(NSString *)color
{
    ...
    //do stuff to default the dark and light image name and which UIView to animate based on the color parameter
    ...
    [UIView transitionWithView:imageView
                  duration:.5
                   options: UIViewAnimationOptionTransitionCrossDissolve | UIViewAnimationOptionAutoreverse
                animations:^{
                    imageView.image = [UIImage imageNamed:lightImage];
                } 
                completion:^(BOOL finished){
                    if (finished){
                        imageView.image = [UIImage imageNamed:darkImage];
                    }
                }];
}

This works fine when I call it the method this code in with one color.

The problem is, say I have an NSArray or colors I want to animate sequentially. So if my array was "blue","green" I would want the transitionWithView to be called using blue, animate the blue view, then animate the green view. Right now, it will animate the green view and the blue view at the same time.

I'm trying to play around with NSTimer right now, but not having much luck with that.

Any advice out there would be much appreciated.

Reveille answered 1/7, 2012 at 17:52 Comment(0)
R
3

OK, so after playing around some/a lot I found a solution. First, I changed the transitionWithView to look like this:

[UIView transitionWithView:imageView
                  duration:1
                   options: UIViewAnimationOptionTransitionCrossDissolve
                animations:^{
                    imageView.image = [UIImage imageNamed:lightImage];
                } 
                completion:^(BOOL finished){
                    if (finished){
                        [UIView transitionWithView:imageView
                                          duration:1
                                           options:UIViewAnimationOptionTransitionCrossDissolve
                                        animations:^{
                                            imageView.image = [UIImage imageNamed:darkImage];
                                        }
                                        completion:^(BOOL done){
                                            if (done){
                                                // Do some program upkeep logic 
                                            }
                                        }
                         ];
                    }
                }
 ];

The big change above was removing the original UIViewAnimationOptionAutoreverse I had, and add the animation to go from the light image to the dark image in the completion block.

Then to call the above method (animateColor:), I loop through an array and use a perform selector with an increasing afterDelay:

    for (NSString *color in self.randomPattern.patternArray) {
        [self performSelector:@selector(animateColor:) withObject:color afterDelay:1.5*self.counter];
        ++self.counter;
    }
Reveille answered 9/7, 2012 at 2:9 Comment(0)
D
5

I had a similar issue when I tried to execute multiple transitions consecutively. I solved it by simply setting a state variable within the completion block. Then this state variable enables the condition for the next transition. Well, since I'm using a timer with a runloop method my work was easier here:

- (void) runloop {

    static int step = 1;

    if (step == 1)
    {
        step = 0;
        [UIView transitionWithView:imageView
                          duration:1
                           options:UIViewAnimationOptionTransitionCrossDissolve
                        animations:^{ imageView.image = [UIImage imageNamed:lightImage]; }
                        completion:^(BOOL finished){ step = 2; }];
    }

    if (step == 2)
    {
        step = 0;
        [UIView transitionWithView:imageView
                          duration:1
                           options:UIViewAnimationOptionTransitionCrossDissolve
                        animations:^{ imageView.image = [UIImage imageNamed:darkImage]; }
                        completion:^(BOOL finished){ step = 0; }];
    }
}

This way you can make dozens of transitions without getting lost into nested blocks.

Diu answered 8/10, 2012 at 20:2 Comment(0)
R
3

OK, so after playing around some/a lot I found a solution. First, I changed the transitionWithView to look like this:

[UIView transitionWithView:imageView
                  duration:1
                   options: UIViewAnimationOptionTransitionCrossDissolve
                animations:^{
                    imageView.image = [UIImage imageNamed:lightImage];
                } 
                completion:^(BOOL finished){
                    if (finished){
                        [UIView transitionWithView:imageView
                                          duration:1
                                           options:UIViewAnimationOptionTransitionCrossDissolve
                                        animations:^{
                                            imageView.image = [UIImage imageNamed:darkImage];
                                        }
                                        completion:^(BOOL done){
                                            if (done){
                                                // Do some program upkeep logic 
                                            }
                                        }
                         ];
                    }
                }
 ];

The big change above was removing the original UIViewAnimationOptionAutoreverse I had, and add the animation to go from the light image to the dark image in the completion block.

Then to call the above method (animateColor:), I loop through an array and use a perform selector with an increasing afterDelay:

    for (NSString *color in self.randomPattern.patternArray) {
        [self performSelector:@selector(animateColor:) withObject:color afterDelay:1.5*self.counter];
        ++self.counter;
    }
Reveille answered 9/7, 2012 at 2:9 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.