Second touch animation

2020-05-08 03:19发布

问题:

Trying to get to grips with Xcode and seem to be making some progress over the last few weeks.

Does anyone know a way that a custom button can do a different set of animations on a second click.

So let say I have a custom button and its of Mario, when i click it he runs from the middle of the screen and out of the right hand side of the screen and then runs back in to the middle from the left of the screen, he also makes noise.

I have achieved this using this code:

- (IBAction)marioRunning_clicked:(id)sender
{

    [UIView animateWithDuration:1.50 delay:0.0 options:UIViewAnimationOptionBeginFromCurrentState animations:^{
        marioRunning.center = CGPointMake(350.5, 456.0);
    } completion:^(BOOL finished) {
        if (finished) {
            [UIView animateWithDuration:0.00 delay:0.0 options:UIViewAnimationOptionBeginFromCurrentState animations:^{
                marioRunning.center = CGPointMake(-30.5, 456.0);
            } completion:^(BOOL finished) {
                if (finished) {
                    [UIView animateWithDuration:1.50 delay:0.0 options:UIViewAnimationOptionBeginFromCurrentState animations:^{
                        marioRunning.center = CGPointMake(160.0, 456.0);
                    } completion:^(BOOL finished) {
                        if(finished)  // NSLog ( @"Finished !!!!!" );
                        marioRunning.center = CGPointMake(160.0, 456.0);
                    }];
                }
            }];
        }
    }];

    marioRunning.imageView.animationImages = [NSArray arrayWithObjects:[UIImage imageNamed:@"mario-running2"],[UIImage imageNamed:@"mario-running3"],nil];

    marioRunning.imageView.animationDuration = 0.15;
    marioRunning.imageView.animationRepeatCount = 19;

    [marioRunning.imageView startAnimating];
}

How could I make him do a second set of animations on the next click? For example instead of running from left to right, if i tap him the second time he will Jump up and down?

回答1:

Use the selected state of the button to decide which animation to do

-(void)buttonClicked:(UIButton*)button
{
     if(button.selected)
     {
          [self doAnimation1];
     }
     else
     {
          [self doAnimation2];
     }

     button.selected = !button.selected;
}


回答2:

This might be overkill, but here's a cool way to do what you want:

Make a subclass of UIButton, and let's call it DDDMarioButton:

typedef void (^DDDAnimationBlock)(UIButton *button);

@interface DDDMarioButton : UIButton

- (void)addAnimationBlockToQueue:(DDDAnimationBlock)block;

@end

Then in DDDMarioButton.m:

@interface DDDMarioButton ()

@property (nonatomic, strong) NSMutableArray *animationQueue;

@end

@implementation DDDMarioButton

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        [self addTarget:self action:@selector(buttonPressed:) forControlEvents:UIControlEventTouchUpInside];
    }
    return self;
}

- (void)buttonPressed:(id)button
{
    DDDAnimationBlock block = self.animationQueue[0];
    block(self);
    [self.animationQueue removeObjectAtIndex:0];
}

- (void)addAnimationBlockToQueue:(DDDAnimationBlock)block
{
    if(!self.animationQueue)
    {
        self.animationQueue = [NSMutableArray new];
    }

    [self.animationQueue addObject:block];
}

@end

and then wherever you create your buttons, you add each step one by one:

DDDMarioButton *button = [[DDDMarioButton alloc] initWithFrame:CGRectZero];

[button addAnimationBlockToQueue:^(UIButton *button) {
   // perform some animation
}];

[button addAnimationBlockToQueue:^(UIButton *button) {
    // perform another animation
}];

And that should do it. I haven't tested this, you'll probably need some configuration, but that's pretty much the idea.