title: How to keep iOS animation smooth with many subviews
body: <p>I am trying out different looks of a little game I am writing to play with animation on iOS.</p>
  
  <p>My goal is this to have a grid of tiles which based on gameplay changes the display of each tile to one of a set of images. I'd like each tile (up to 24x24) to flip around when its face changes. As the game progresses, more and more tiles need to be flipped at the same time. In the first implementation where I tried to flip them simultaneously the animation got very jerky.</p>
  
  <p>I changed my approach to not flip them all at once, but just a few at a time, by scheduling the animation for each tile with a slightly increasing delay per tile, so that when say the 10th tile starts animating, the first one is already done. It takes little while longer for the whole process to finish, but also leads to a nice visual ripple-effect.</p>
  
  <p><img src="https://i.stack.imgur.com/QoyuX.png" alt="Screen shot from the simulator"></p>
  
  <p>However, one problem remains: At the beginning of a game move, when the player picks a new color, it takes a few fractions of a second on the device, before the animation starts. This gets worse as the game progresses and more flips need to be scheduled per move, up to the point where the animation seems to hang and then completes almost instantly without any of the frames in between being actually discernible.</p>
  
  <p>This is the code (in my <code>UIView</code> game grid subclass) that triggers the flipping of relevant tiles. (I removed an optimization that skips tiles, because it only matters in the early stages of the game).</p>
  
  <pre><code>float delay = 0.0f;
  for (NSUInteger row=0; row&lt;numRows; row++) {
      for (NSUInteger col=0; col&lt;numCols; col++) {
          delay += 0.03f;
          [self updateFlippingImageAtRow:row col:col delay:delay animated:YES];
      }
  }
  </code></pre>
  
  <p>The game grid view has an <code>NSArray</code> of tile subviews which are addressed using the <code>row</code> and <code>col</code> variables in the loop above.</p>
  
  <p><code>updateFlippingImageAtRow:col:delay:animated</code> is a method in my <code>FlippingImageView</code> (also a subclass of <code>UIView</code>) boils down to this (game logic omitted):</p>
  
  <pre><code>-(void)animateToShow:(UIImage*)image 
              duration:(NSTimeInterval)time 
                 delay:(float)delay 
            completion:(void (^)(BOOL finished))completion 
  {
      [UIView animateWithDuration:time
                            delay:delay
                          options:UIViewAnimationOptionTransitionFlipFromLeft 
                       animations:^{
                           [UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft
                                                  forView:self
                                                    cache:YES];
                           self.frontImage = image;
                       }
                       completion:completion
      ];
  }
  </code></pre>
  
  <p>Works fine, however, I conclude from the Instruments measuring which tells me that my time is spent in the animation block, that as the game goes on and the number of tiles to flip goes up, that the number of animations that get scheduled at the very beginning of the operation is a problem, and that the system then tries to catch up by dropping frames.</p>
  
  <p><img src="https://i.stack.imgur.com/NJY4C.png" alt="Instruments screen shot of a few flip operations"></p>
  
  <p>Any suggestions how to improve the performance of this? The exact timing of the animation is not really important.</p>