title: CADisplayLink & UIView Animations Unreliable
body: <p>I am trying to create an Animations Manager class, which will handle recursive animations for me. It is working, but is being unreliable. e.g Sometimes, when using it the animations happen "back to back" as it were, with no delay between them. Other times when using it, delays are left between animations (This is happening on other elements located on other view controllers)</p>
  
  <p>Here is my code:</p>
  
  <pre><code>@implementation customAnimationTimer
  
  -(id) initWithTimeInterval:(NSTimeInterval)timeInterval target:(UIView*)target animationType:(NSInteger)animationType
                fromValue:(CGFloat)fromValue toValue:(CGFloat)toValue withDelegate:(id &lt;customAnimationTimerDelegate&gt;)delegate {
  
      if (self = [super init]) {
          self.delegate = delegate;
          _timeInterval = timeInterval;
          _target = target;
          _animationState = NO;
          _animationType = animationType;
          _fromValue = fromValue;
          _toValue = toValue;
  
          _displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(displayLinkFire)];
          [_displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes];
      }
      return self;
  }
  
  -(void) displayLinkFire {if (self.delegate) [self.delegate displayLinkUpdate:self];}
  
  @end
  
  
  @implementation animationManager
  
  
  static animationManager* sharedHelper = nil;
  
  + (animationManager*) sharedInstance {
      if (!sharedHelper) sharedHelper = [[animationManager alloc] init];
      return sharedHelper;
  }
  
  
  -(id) init { if (self = [super init]) {[self initArrays];} return self;}
  
  -(void) initArrays {
      _activeTimers = [NSMutableArray arrayWithObjects: nil];
  }
  
  -(void) displayLinkUpdate:(customAnimationTimer*)timer {
      if (timer.displayLink.frameInterval != 1) [self animateWithTimer:timer];
      timer.displayLink.frameInterval = (timer.timeInterval/timer.displayLink.duration);
  }
  
  -(void) animateWithTimer:(customAnimationTimer*)timer {
      if (!timer.animationState) {
  
          timer.animationState = true;
          [UIView animateWithDuration:timer.timeInterval animations:^{
             if (timer.animationType == 0) timer.target.alpha = timer.toValue;
          }];
  
      } else {
  
          timer.animationState = false;
          [UIView animateWithDuration:timer.timeInterval animations:^{
              if (timer.animationType == 0) timer.target.alpha = timer.fromValue;
          }];
  
      }
  }
  
  -(void) addAnimationToView:(UIView*)view withType:(int)animationType fromValue:(CGFloat)fromValue toValue:(CGFloat)toValue withTime:(CGFloat)time  {
      [_activeTimers addObject: [[customAnimationTimer alloc] initWithTimeInterval:time target:view animationType:animationType fromValue:fromValue toValue:toValue withDelegate:self]];
  }
  
  -(void) removeAnimationFromView:(UIView*)view {
  
      NSInteger index = 900000000;
      for (customAnimationTimer* timer in _activeTimers) {
          if (timer.target == view) {
              index = [_activeTimers indexOfObject:timer];
              [timer.displayLink invalidate];
          }
      }
  
      if (index != 900000000) [_activeTimers removeObjectAtIndex:index];
  
  }
  
  -(void) removeAnimations {
      for (customAnimationTimer* timer in _activeTimers) [timer.displayLink invalidate];
      [self initArrays];
  }
  
  
  @end
  </code></pre>