Reputation: 3
I have 9 custom subviews that I create and lay out programmatically. I want to animate their creation and change of position each one at a time but right now the whole set of 9 subviews is being animated at the same time.
This is my code:
- (void)viewDidLoad{
//create 9 setCardViews and add them to the array setCards to be able to identify them later
for (int i=0; i<9; i++) {
SetCardView *card = [[SetCardView alloc]initWithFrame:CGRectMake(self.gameView.center.x, self.gameView.center.y, 0, 0)];
[self.gameView addSubview:card];
[self.setCards addObject:card];
}
//layout those 9 views
[self updateLayout];
}
Then, the updateLayout method is called. It sets a frame size inside of which the subviews are laid out:
-(void)updateLayout
{
CGRect canvas = [self resizeCanvasWithNumberOfCards:[self.setCards count]];
for (SetCardView *card in self.setCards)
{
[self layOutCard:card withFrame:canvas atIndex:[self.setCards indexOfObject:card]];
}
}
Finally, inside the layOutCard method I calculate the position of the view (I omit that part of the code here) and I animate the change in its frame:
-(void)layOutCard:(SetCardView *)card withFrame:(CGRect)canvas atIndex:(NSUInteger)index
{
//calculate the new frame of the view
CGRect rect = //calculations ;
[SetCardView animateWithDuration:0.5 delay:self.delay options: UIViewAnimationOptionCurveEasyInOut animations:^{card.frame=rect;} completion:nil];
}
So all these animations happen at the same time, maybe because it's inside a loop in the updateLayout method so the controller waits for it to finish? Anyway I can't think of a way to make the animation of the views without using a loop so that they animate one at a time.
How could I do that?
Thanks
Upvotes: 0
Views: 142
Reputation: 25459
One of the way you can make it works is increase delay when you enumerate cards in updateLayout and after that pass it to layOutCard:withFrame:atIndex (of course you have to add delay parameter to that method. Or ft index parameter start from 0 and increase by 1 every time you can use it to calculate delay:
-(void)layOutCard:(SetCardView *)card withFrame:(CGRect)canvas atIndex:(NSUInteger)index
{
//calculate the new frame of the view
CGRect rect = //calculations ;
float myDelay = 0.5 * index; //0.5 is your duration.
[SetCardView animateWithDuration:0.5 delay: myDelay options: UIViewAnimationOptionCurveEasyInOut animations:^{card.frame=rect;} completion:nil];
}
Upvotes: 1
Reputation: 4143
You have it done (almost). One small adjustment on your code. At a run time your for
loop is executed very fast leaving you with the impression that all animations are starting at the same time. You are using start with delay on your animation block already so simply increase the delay every time you go into to loop
like this.
-(void)updateLayout
{
CGRect canvas = [self resizeCanvasWithNumberOfCards:[self.setCards count]];
for (SetCardView *card in self.setCards)
{
[self layOutCard:card withFrame:canvas atIndex:[self.setCards indexOfObject:card]];
// increase the delay so next animation will start after this one is finished
// check if this card is the last from your array
if([card isEqual:[self.setCards lastObject]])
{
// if card is last object set self.delay back to 0
self.delay = 0;
{
else
{
// if card is not the last object increase the delay time for next animation
self.delay += 0.5; // your current animation duration
}
}
}
Upvotes: 0