title: Swapping UIImageView Images in a loop
body: <p>I have a NSArray of UIImageViews that I want to loop over and quickly swap out an "on" and "off" state. I wrote the code to do so in a for loop instead a method that was called when the user tapped a UIButton ( the button's action ). </p>
  
  <p>Here's that loop:</p>
  
  <pre><code>for(int i = 0; i &lt; [Images count]; i++) {
      if( i &gt; 0 ){
          [self toggleImageViewOff:[Images objectAtIndex:i - 1]];
      }
  
      [self toggleImageViewOn:[Images objectAtIndex:i]];
  
      [NSThread sleepForTimeInterval:0.5f];
  }
  </code></pre>
  
  <p>The UI did not update as I expected as I only ever saw the last UIImageView in the "on" state. I figured that the drawing update of the views must occur in the main thread this code was also executing in. So I learned about performSelectorInBackground:withObject: . Performing the toggleImageViewOn/Off methods using this made the loop work. The problem is if I make the sleep interval too short I can have an "on" update after an "off" with Threads operating out of order. </p>
  
  <p>So I had the bright idea of moving the whole loop with the sleep into its own method and calling that from the action method using performSelectorInBackground:withObject: . I tried that and I'm back to not getting an updated view until the loop is over. </p>
  
  <p>That's a long winded way to get to my question:</p>
  
  <p>What's the best way to animate this to guarantee the on/off code fires in the right order and still get view updates, even at high speeds? ( i.e. looping very quickly ) </p>
  
  <p>I tried to think about how I'd do it with CoreAnimation, but I can't seem to get my head around how to do it there. </p>
  
  <p>For bonus, here are the toggle methods:</p>
  
  <pre><code>- (void)toggleImageViewOn:(UIImageView *)theImageView {
      [theImageView setImage:[UIImage imageNamed:@"on.png"]];
  }
  
  - (void)toggleImageViewOff:(UIImageView *)theImageView {
      [theImageView setImage:[UIImage imageNamed:@"off.png"]];
  }
  </code></pre>