// I grew up programming-wise on the Apple //+.  Back then we had flashing text, and we liked it.
  
  /
  / I recently needed it in a Cocoa app I was writing. So I wrote a simple subclass of NSLabel/UILabel to flash text.
  // Because I think flashing text is the future of computing, here it is.  
  
// Of course, works fine on iOS too, just define __FORIOS__ 
// And yes I know all my OS X/iOS ifdefs look backwards.  This is the way my brain works.
// Download the source files so you don't have to cut and paste aiiFlashingText
// Provided under the Fredware License
//
  // aiiFlashingText.h
  //
  //  Created by C.K. Haun on 12/24/13.
  //  Copyright (c) 2013 C.K. Haun and Ravenware Industries LLC. All rights reserved.
  //
  #ifndef __FORIPHONE__
  #import <Cocoa/Cocoa.h>
  #else
  #import <UIKit/UIKit.h>
  #endif 
  typedef enum textFlashSpeed{
textFlashSpeedFast=0,
textFlashSpeedMedium,
textFlashSpeedSlow
}textFlashSpeed;
// silly macros to harmonize OS X and iOS which already should be harmonized
  #ifndef __FORIPHONE__
  #define aiiColor NSColor
  #define aiiRect NSRect
  #else
  #define aiiColor UIColor
  #define aiiRect CGRect
#endif
@interface aiiFlashingText :
  #ifndef __FORIPHONE__
  NSTextField
  #else
  UILabel
  #endif
  {
  aiiColor *textColor;
  NSTimer *timit;
  BOOL onoff;
  BOOL flashing;
  BOOL oldFlashing;
  NSTimeInterval currentSpeed;
  NSTimeInterval flashSpeed[3];
  }
-(void)applyColor:(aiiColor *)newColor;
  -(void)setFlashSpeed:(textFlashSpeed)speed;
  -(void)flash:(BOOL)startStop;
  @end
//
  //  aiiFlashingText.m
  //  Machine Essays
  //
  //  Created by C.K. Haun on 12/24/13.
  //  Copyright (c) 2013 C.K. Haun and Ravenware Industries LLC. All rights reserved.
//
#import "aiiFlashingText.h"
  @interface aiiFlashingText()
  -(void)doFlashie:(NSTimer *)thi;
  -(void)innerInit;
@end
  @implementation aiiFlashingText
  -(void)innerInit{
  int qq;
  NSTimeInterval aa[]={.2,.7,1.3};
  for(qq=0;qq<3;qq++)
  flashSpeed[qq]=aa[qq];
  currentSpeed=.7;
  }
  - (id)initWithFrame:(aiiRect)frame
  {
  self = [super initWithFrame:frame];
  if (self) {
  [self innerInit];
  }
  return self;
  }
  -(void)awakeFromNib {
  [self innerInit];
  }
  -(void)applyColor:(aiiColor *)newColor{
  [self setTextColor:newColor];
  }
  -(void)setFlashSpeed:(textFlashSpeed)speed{
  currentSpeed=flashSpeed[speed];
  if(flashing)
  [timit invalidate];
  timit = [NSTimer scheduledTimerWithTimeInterval: currentSpeed target:self selector:@selector(doFlashie:) userInfo:nil repeats: YES];
  onoff = NO;
  flashing=YES;
  }
  // override setHidden to turn off the timer
  -(void)setHidden:(BOOL)flag{
  [super setHidden:flag];
  if(flag==NO){
  // if it was previously hidden flashing, turn it visible again flashing.  If not, well, don't
  [self flash :oldFlashing];
  }else {
  oldFlashing=flashing;
  [self flash:NO];
  }
  }
// inner routine called byu the timer to ramp between solid and transparent
  -(void)doFlashie:(NSTimer *)thi{
  if(onoff){
  onoff=NO;
  #ifndef __FORIPHONE__
  [[self animator] setAlphaValue:0];
  #else
  [UIView animateWithDuration:currentSpeed animations:^(void) {
  self.alpha = 0;
  }];
  #endif
  }else{
  onoff=YES;
  #ifndef __FORIPHONE__
 [[self animator] setAlphaValue:1];
  #else
  [UIView animateWithDuration:currentSpeed animations:^(void) {
  self.alpha = 1;
  }];
  #endif
  
  }
  }
// start or stop flashing here
  -(void)flash:(BOOL)startStop{
  if(startStop){
  // want to start in fully visible
  #ifndef __FORIPHONE__
  
  [[self animator] setAlphaValue:1];
  #else
  [UIView animateWithDuration:currentSpeed animations:^(void) {
  self.alpha = 1;
  }];
  #endif
  timit = [NSTimer scheduledTimerWithTimeInterval: currentSpeed target:self selector:@selector(doFlashie:) userInfo:nil repeats: YES];
  flashing=YES;
  } else {
  onoff=YES;
  if(timit)
  [timit invalidate];
  timit = nil;
  #ifndef __FORIPHONE__
  
  [[self animator] setAlphaValue:1];
  #else
  [UIView animateWithDuration:currentSpeed animations:^(void) {
  self.alpha = 1;
  }];
  #endif
  flashing=NO;
 }
  }
  // overriding dealloc even with ARC to kill the timer.  Not strictly necessary since the timer will
  // be cleared at some point and ARC will handle it, but I don't want it to fire off when the text is in an indeterminate state.
  -(void)dealloc{
  if(timit!=nil)
  [timit invalidate];
  }
  @end