iosios7uidynamicbehavioruidynamicanimator

Is it possible to snap UIViews using UISnapBehavior consecutively


I am working on CS193P and I would like to create an effect where cards fly in from the 0,0 one after another snapping into place. I tried to chain the animation but the views flying together also I am trying to use UIDynamicAnimator and same thing happens. All the views are snapping together. Here is the code that i have to snap the views.

-(void)snapCardsForNewGame
{
    for (PlayingCardView *cardView in self.cards){
        NSUInteger cardViewIndex = [self.cards indexOfObject:cardView];
        int cardColumn = (int) cardViewIndex / self.gameCardsGrid.rowCount;
        int cardRow = (int) cardViewIndex % self.gameCardsGrid.rowCount;
        UISnapBehavior *snapCard = [[UISnapBehavior alloc]initWithItem:cardView snapToPoint:[self.gameCardsGrid centerOfCellAtRow:cardRow inColumn:cardColumn]];
        snapCard.damping = 1.0;
        [self.animator addBehavior:snapCard];

    }


}


-(void)newGame
{
    NSUInteger numberOfCardsInPlay = [self.game numberOfCardsInPlay];
    for (int i=0; i<numberOfCardsInPlay; i++) {
        PlayingCardView *playingCard = [[PlayingCardView alloc]initWithFrame:CGRectMake(0, 0, 50, 75)];
        playingCard.faceUp = YES;
        [playingCard addGestureRecognizer:[[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(flipCard:)]];
        [self.cards addObject:playingCard];
        //NSUInteger cardViewIndex = [self.cards indexOfObject:playingCard];
        //int cardColumn = (int) cardViewIndex / self.gameCardsGrid.rowCount;
        //int cardRow = (int) cardViewIndex % self.gameCardsGrid.rowCount;

       // playingCard.frame = [self.gameCardsGrid frameOfCellAtRow:cardRow inColumn:cardColumn];
        playingCard.center = CGPointMake(0, 0);
        [self.gameView addSubview:playingCard];
        [self snapCardsForNewGame];
    }
}

Does it even make sense to use it in this situation? I tried few different things to get the cards fly in one by one but wasn't able to.

Thanks in advance!


Solution

  • Since you're adding all the UISnapBehaviors at the same time, the animator runs them all together. Delay adding them to the animator and they'll be animated on their own.

    -(void)snapCardsForNewGame
    {
        for (PlayingCardView *cardView in self.cards){
            NSUInteger cardViewIndex = [self.cards indexOfObject:cardView];
            int cardColumn = (int) cardViewIndex / self.gameCardsGrid.rowCount;
            int cardRow = (int) cardViewIndex % self.gameCardsGrid.rowCount;
            UISnapBehavior *snapCard = [[UISnapBehavior alloc]initWithItem:cardView snapToPoint:[self.gameCardsGrid centerOfCellAtRow:cardRow inColumn:cardColumn]];
            snapCard.damping = 1.0;
    
            NSTimeInterval delayTime = 0.01 * cardViewIndex;
            dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayTime * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
                [self.animator addBehavior:snapCard];
            });
        }
    }