2014-12-24 2 views
1

그래서 여기에 내가하려고하는 것이 있습니다. 발생하는 애니메이션 대기열이 있어야합니다. 이는 효과를 망치고 대기열의 마지막 애니메이션 만 표시하기 때문에 일시적으로 발생할 수 없습니다. 새 애니메이션을 시작하기 전에 이전 애니메이션이 완료 될 때까지 기다리는 대기열을 어떻게 만들 수 있습니까?다른 하나가 끝난 후에 발생하는 애니메이션 대기열을 구현하는 방법

다음은 xpItems 배열의 최종 애니메이션만을 보여줍니다.

  var xpItems = XPItem.loadCustomObjectWithKey() 
      for (var i = 0; i < xpItems.count; i++) { //for each XP Item. 
       let rewardName = xpItems[i].title 
       let rewardAmount = xpItems[i].xpAmount 
       println(rewardName + " " + String(rewardAmount)) 

       let currentLevelXPRequired = 100 
       let newProgress = CGFloat(rewardAmount)/CGFloat(currentLevelXPRequired) as CGFloat 

       self.xpCircle.setProgress(xpCircle.progress + newProgress, animated: true) 

      } 

// 나머지 코드는 Obj-c입니다.

- (void)setProgress:(CGFloat)progress animated:(BOOL)animated 
{ 
    if (self.progress == progress) { 
     return; 
    } 
    if (animated == NO) { 
     if (_displayLink) { 
      //Kill running animations 
      [_displayLink removeFromRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes]; 
      _displayLink = nil; 
     } 
     [self setNeedsDisplay]; 
    } else { 
     _animationStartTime = CACurrentMediaTime(); 
     _animationFromValue = self.progress; 
     _animationToValue = progress; 
     if (!_displayLink) { 
      //Create and setup the display link 
      [self.displayLink removeFromRunLoop:NSRunLoop.mainRunLoop forMode:NSRunLoopCommonModes]; 
      self.displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(animateProgress:)]; 
      [self.displayLink addToRunLoop:NSRunLoop.mainRunLoop forMode:NSRunLoopCommonModes]; 
     } /*else { 
      //Reuse the current display link 
     }*/ 
    } 
} 


- (void)animateProgress:(CADisplayLink *)displayLink 
{ 
    dispatch_async(dispatch_get_main_queue(), ^{ 
     CGFloat dt = (displayLink.timestamp - _animationStartTime)/self.animationDuration; 
     if (dt >= 1.0) { 
      //Order is important! Otherwise concurrency will cause errors, because setProgress: will detect an animation in progress and try to stop it by itself. Once over one, set to actual progress amount. Animation is over. 
      [self.displayLink removeFromRunLoop:NSRunLoop.mainRunLoop forMode:NSRunLoopCommonModes]; 
      self.displayLink = nil; 
      [super setProgress:_animationToValue animated:NO]; 
      [self setNeedsDisplay]; 
      return; 
     } 

     //Set progress 
     [super setProgress:_animationFromValue + dt * (_animationToValue - _animationFromValue) animated:YES]; 
     [self setNeedsDisplay]; 

    }); 
} 

super.setProgress [...]

코드 OBJ-C/신속 될 갖는 약
- (void)setProgress:(CGFloat)progress animated:(BOOL)animated 
{ 
    _progress = progress; 
} 

미안.

+0

재귀 개념 사용 – Kampai

+0

난 당신이 작업 대기열을 사용하여 시도하고 동시성을 1로 설정하고 다른 후 하나의 애니메이션을 dequeue 논리를 정의 할 수 있다고 생각 – Dinakar

+0

예를 들어 줄래? 감사합니다 – CaptainCOOLGUY

답변

3

확실히 대부분의 애니메이션 메서드에는 애니메이션이 완료 될 때 선택적으로 호출되는 완료 핸들러가 있습니다. UIView 또는 애니메이션을 수행 할 수있는 다른 객체 (어쩌면 배열 CGPoint)를 만든 다음 모든 객체를 순서대로 애니메이션으로 만들면됩니다. 예 :

- (void)animateArrayWithCompletion:(void(^)(void))handler 
{ 
    if (!viewArray.count) { 
     if (handler) { 
      handler(); 
     } 
    } 
    else { 
     UIView *myView = viewArray.lastObject; 
     [viewArray removeObject:myView]; 
     CGRect frame = myView.frame; 
     frame.origin.x += 100; 
     [UIView animateWithDuration:1 animations:^{ 
      myView.frame = frame; 
     } completion:^(BOOL complete) { 
      [self animateArrayWithCompletion:handler]; 
     }]; 
    } 
} 
+0

나는 이것을 많이 좋아합니다! 감사 – CaptainCOOLGUY