Как заставить две анимации просмотра запускаться одна за другой?

Я должен сделать игру «Угадай карту», ​​то есть: в окнах есть 24 карты (UIImageView) со скрытой внутренней поверхностью, отображаемой на поверхности, они представляют собой 12 групп, вы касаетесь одной, затем она будет открыта. Показать внутри, найти если открыта одна и та же карта, если не совпадают, две открытые карты будут скрыты.

Просто это.

действие открытой карты и скрытия карты использовало анимацию UIView. Но теперь у меня проблема. Когда я прикасаюсь к карте, она пытается найти, есть ли совпадение. Но анимация действия открытой карты и закрытия карты выполняется одновременно. даже я не могу видеть, какой контент карты я вижу ясно.

Я хочу открыть карту после того, как коснусь ее, а затем (даже подождите 0,5 секунды) одновременно закройте открытые несопоставленные карты. не открывайте карту и не закрывайте карту одновременно. Но в моем коде ниже я сначала открыл карту, затем вычислил и закрыл две открытые карты.

@interface Card : UIImageView

@property BOOL expanded;
@property BOOL found;
@property (retain)NSString * nameTitle;
@property (retain) UIImage * expandedImage;

@end


//
//  Card.m
//  Guest card match
//
//  Created by  on 11-10-20.
//  Copyright 2011年 __MyCompanyName__. All rights reserved.
//

#import "Card.h"
#import "MainAppDelegate.h"

@implementation Card
@synthesize expanded;
@synthesize found;
@synthesize expandedImage;
@synthesize nameTitle;

- (id)init
{
    if ((self = [super init])) {
        [self setUserInteractionEnabled:YES];
        self.image = [UIImage imageNamed:@"cardface_48.png"];
        self.expanded = NO;
        self.found = NO;
    }
    return self;
}

- (void)openCard{
    NSLog(@"open card");
    if (self.expanded){return;}
    self.expanded = YES;
    [UIView beginAnimations:@"animation1" context:nil]; 
    [UIView setAnimationDuration:0.8];
    [UIView setAnimationDelegate:self];

    [UIView setAnimationBeginsFromCurrentState:YES];
    [UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:self cache:YES];
    [self setTransform:CGAffineTransformMakeScale(3.0, 3.0)];
    [self setImage:self.expandedImage];
    [UIView commitAnimations];

    [UIView beginAnimations:@"animation1_open" context:nil]; 
    [UIView setAnimationDuration:1.2];
    [UIView setAnimationDelegate:self];

    [UIView setAnimationBeginsFromCurrentState:NO];
    [self setTransform:CGAffineTransformMakeScale(1, 1)];
    [UIView commitAnimations];


}

- (void)closeCard{
    if (!self.expanded){return;}
    self.expanded = NO;

    [UIView beginAnimations:@"animation1_close" context:nil]; 
    [UIView setAnimationDuration:0.8];
    [UIView setAnimationDelegate:self];


    [UIView setAnimationBeginsFromCurrentState:YES];
    [UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:self cache:YES];
    [self setTransform:CGAffineTransformMakeScale(3.0, 3.0)];
    [self setImage:[UIImage imageNamed:@"cardface_48.png"]];
    [UIView commitAnimations];

    [UIView beginAnimations:@"animation2_close" context:nil]; 
    [UIView setAnimationDuration:1.2];
    [UIView setAnimationDelegate:self];


    [UIView setAnimationBeginsFromCurrentState:NO];
    [self setTransform:CGAffineTransformMakeScale(1, 1)];
    [UIView commitAnimations];
    [self setUserInteractionEnabled:YES];


}


- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { 
    // Do what you want here 
    //NSLog(@"touchesBegan!"); 
    //[self setUserInteractionEnabled:NO];
} 

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { 

    NSLog(@"card tag: %d", self.tag);
    if (self.expanded) {
        return;
    }

    [self openCard];
    for (NSInteger tagNumber=10001; tagNumber<10025; tagNumber++) {
        Card *card = (Card *)[self.superview viewWithTag:tagNumber];
        if (card.expanded && card.tag != self.tag && !card.found) {
            if ([card.nameTitle isEqualToString:self.nameTitle]) {// Found match!
                NSLog(@"Match!");
                [card setUserInteractionEnabled:NO];
                [self setUserInteractionEnabled:NO];
                card.found = YES;
                self.found = YES;
            }else{
                NSLog(@"not Match!");
                [card closeCard];
                [self closeCard];

            }
        }else{
           [self setUserInteractionEnabled:YES]; 
        }
    }


} 

@end

Обновление: я следил за Кашивом, и этот обновленный код:

- (void)openCard{
    NSLog(@"open card");
    if(cardAnimationIsActive) return;
    cardAnimationIsActive = YES;


    if (self.expanded){return;}
    self.expanded = YES;


    [UIView animateWithDuration:2.0f animations:^{


        [UIView beginAnimations:@"animation1" context:nil]; 
        [UIView setAnimationDuration:0.8];
        [UIView setAnimationDelegate:self];

        [UIView setAnimationBeginsFromCurrentState:YES];
        [UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:self cache:YES];
        [self setTransform:CGAffineTransformMakeScale(3.0, 3.0)];
        [self setImage:self.expandedImage];
        [UIView commitAnimations];

        [UIView beginAnimations:@"animation1_open" context:nil]; 
        [UIView setAnimationDuration:1.2];
        [UIView setAnimationDelegate:self];

        [UIView setAnimationBeginsFromCurrentState:NO];
        [self setTransform:CGAffineTransformMakeScale(1, 1)];
        [UIView commitAnimations];



    } completion:^(BOOL finished){
        cardAnimationIsActive = NO;
    }];




}

- (void)closeCard{

    if(cardAnimationIsActive) return;
    cardAnimationIsActive = YES;

    if (!self.expanded){return;}
    self.expanded = NO;

    [UIView animateWithDuration:5.0f animations:^{
        [UIView beginAnimations:@"animation1_close" context:nil]; 
        [UIView setAnimationDuration:0.8];
        [UIView setAnimationDelegate:self];


        [UIView setAnimationBeginsFromCurrentState:YES];
        [UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:self cache:YES];
        [self setTransform:CGAffineTransformMakeScale(3.0, 3.0)];
        [self setImage:[UIImage imageNamed:@"android_48.png"]];
        [UIView commitAnimations];

        [UIView beginAnimations:@"animation2_close" context:nil]; 
        [UIView setAnimationDuration:1.2];
        [UIView setAnimationDelegate:self];


        [UIView setAnimationBeginsFromCurrentState:NO];
        [self setTransform:CGAffineTransformMakeScale(1, 1)];
        [UIView commitAnimations];
        [self setUserInteractionEnabled:YES];
    } completion:^(BOOL finished){
        cardAnimationIsActive = NO;
    }];




}

Но анимация opencard и closecard по-прежнему выполняются одновременно.


person qichunren    schedule 26.12.2011    source источник


Ответы (3)


Вы можете добиться этого, используя блочную анимацию:

+ (void)animateWithDuration:(NSTimeInterval)duration animations:(void (^)(void))animations completion:(void (^)(BOOL finished))completion

Затем вы можете проверить, выполняется ли анимация или она уже завершена, используя BOOL iVar (например, cardAnimationIsActive).

Пример:

- (void)openCard {
    if(cardAnimationIsActive) return;
    cardAnimationIsActive = YES;
    [UIView animateWithDuration:duration animations:^{
        --- your open animations ---
    } completion:^(BOOL finished){
        cardAnimationIsActive = NO;
    }];
}

- (void)closeCard {
    if(cardAnimationIsActive) return;
    cardAnimationIsActive = YES;
    [UIView animateWithDuration:duration animations:^{
        --- your close animations ---
    } completion:^(BOOL finished){
        cardAnimationIsActive = NO;
    }];
}
person akashivskyy    schedule 26.12.2011
comment
Я следовал вашему руководству, анимация opencard и closecard по-прежнему выполняется одновременно, а не одна за другой. - person qichunren; 26.12.2011
comment
Возможно, причина проблемы в том, что и в анимации открытой карты, и в анимации закрытия карты есть более одной анимации. - person qichunren; 26.12.2011
comment
Вы можете создавать сложные анимации, помещая их в блок завершения. - person akashivskyy; 26.12.2011
comment
Большое спасибо, я последовал за вами, чтобы создать вставку внутри блока, и, наконец, внутри блока завершения установил для cardAnimationIsActive значение NO; - person qichunren; 26.12.2011

Вы можете использовать:

[UIView setAnimationDelay:delay];

для задержки всех анимаций в нужное время, чтобы они запускались последовательно.

person sergio    schedule 26.12.2011
comment
Я думаю, вы имеете в виду добавить этот код в мою анимацию закрытия карты. Но я пробовал, действие открытой карты и закрытия карты по-прежнему выполняется одновременно. - person qichunren; 26.12.2011

[UIView animateWithDuration: 0,2 анимации: ^ {view.alpha = 0,0;} завершение: ^ (BOOL завершено) { [view removeFromSuperview]; }];

Вы можете создать вторую анимацию в блоке завершения.

person Nikita Ivaniushchenko    schedule 26.12.2011