In a recent project that I worked on, we needed to show the busy state of the application without explicitly writing out anything. After brainstorming different strategies, we finally settled on blinking one of our central buttons in the app to represent that it is busy. iOS makes it really simple to create animations. Here is how we can start such an animation in iOS:

-(void) startFlashingbutton
{
    if (buttonFlashing) return;
    buttonFlashing = YES;
    self.button.alpha = 1.0f;
    [UIView animateWithDuration:0.12
      delay:0.0
      options:UIViewAnimationOptionCurveEaseInOut |
              UIViewAnimationOptionRepeat |
              UIViewAnimationOptionAutoreverse |
              UIViewAnimationOptionAllowUserInteraction
      animations:^{
       self.button.alpha = 0.0f;
   }
   completion:^(BOOL finished){
    // Do nothing
   }];
}

UIViewAnimationOptionAutoreverse causes the animation to be automatically inversed. Since, in the animation we set the alpha from 1.0 to 0.0, it causes it to return back to 1.0 when finishing the animation which blinks that button once. Now, we ask iOS to repeat this animation by passing UIViewAnimationOptionRepeat flag. UIViewAnimationOptionRepeat will repeat the animation indefinitely. But how do we stop this animation then? This is what the UIViewAnimationOptionAllowUserInteraction flag is for. This allows us to stop the animation at a later stage. Here is how we can stop the animation.

-(void) stopFlashingbutton
{
    if (!buttonFlashing) return;
    buttonFlashing = NO;
    [UIView animateWithDuration:0.12
      delay:0.0
      options:UIViewAnimationOptionCurveEaseInOut |
              UIViewAnimationOptionBeginFromCurrentState
      animations:^{
       self.button.alpha = 1.0f;
   }
   completion:^(BOOL finished){
    // Do nothing
   }];
}

Here, we are basically taking up the animation from its current state and setting the alpha to 1.0 without asking iOS to repeat or reverse the animation.

Now, we can begin the animation anytime using [self startFlashingbutton] and stop it later using [self stopFlashingbutton].