iOS:循环链核心动画问题

时间:2012-07-22 20:36:12

标签: iphone ios ipad core-animation core-graphics

我正在尝试在我的应用中制作一些动画,但我遇到了一些错误。一切都从我的“startAnimatingIndicators”方法开始。这种方法的作用是将两条垂直线(它们都在屏幕的每个边缘处)动画到几乎是我主视图的中心。完成后,它会调用另一个动画,这使得两条线最终到达我视图的中心,同时淡入中心的新垂直线。

这个动画链循环(如你所见,是一个递归方法),直到我按下一个调用StopAnimatingIndicators方法的停止按钮。

第一次一切正常,但有时(并非总是),当我第二次运行动画时,它会以不同的方式开始。有时它从中心的两条垂直线开始,然后它们到达各自的屏幕边缘,然后动画正常流动。有时候,两条垂直线都会正常到达它们的中心,然后它们继续移动直到它们到达相反的边缘然后,动画正常流动。

我不知道为什么会这样,所以我希望你能给我一些想法。我认为这可能与我的CGAffinityIdentityTransform有关,但我无法确切地知道问题究竟是什么。我正在使用的代码如下。谢谢!

- (void)startAnimatingIndicators
{
    NSInteger metronomePreset = [(NSNumber*)[self.metronomePresets objectAtIndex:self.metronomePresetIndex] intValue];
    NSTimeInterval duration = (60.0 / metronomePreset);

    CGFloat firstPartXTranslation = self.videoPreviewView.center.x - self.indicatorLeft.center.x - self.indicatorLeft.frame.size.width;
    CGFloat secondPartXTranslation = self.indicatorLeft.frame.size.width;

    [self animateIndicatorsWithFirstPartXTranslation:firstPartXTranslation secondPartXTranslation:secondPartXTranslation andDuration:duration];
}

- (void)animateIndicatorsWithFirstPartXTranslation:(CGFloat)firstPartXVariation secondPartXTranslation:(CGFloat)secondPartXTranslation andDuration:(NSTimeInterval)duration
{
    [UIView animateWithDuration:duration 
                          delay:0 
                        options:UIViewAnimationCurveEaseIn | UIViewAnimationOptionAllowUserInteraction
                     animations:^{
                          self.finishingIndicator.alpha = 0.0;
                          self.indicatorLeft.transform = CGAffineTransformTranslate(self.indicatorLeft.transform, firstPartXVariation, 0.0);
                          self.indicatorRight.transform = CGAffineTransformTranslate(self.indicatorRight.transform, -firstPartXVariation, 0.0);
                      } 
                     completion:^(BOOL finished){
                          if(finished)
                          {
                              [UIView animateWithDuration:ANIMATION_END_DURATION 
                                                    delay:0 
                                                  options:UIViewAnimationCurveLinear | UIViewAnimationOptionAllowUserInteraction
                                               animations:^{
                                                   self.finishingIndicator.alpha = 1.0;
                                                   self.indicatorLeft.transform = CGAffineTransformTranslate(self.indicatorLeft.transform, secondPartXTranslation, 0.0);
                                                   self.indicatorRight.transform = CGAffineTransformTranslate(self.indicatorRight.transform, -secondPartXTranslation, 0.0);
                                               }
                                               completion:^(BOOL finished){
                                                   [self stopAnimatingIndicators];
                                                   if(finished)
                                                   {
                                                       [self animateIndicatorsWithFirstPartXTranslation:firstPartXVariation secondPartXTranslation:secondPartXTranslation andDuration:duration];

                                                       [self playSound:@"metronome" withExtension:@"wav"];
                                                   }
                                               }
                               ];
                          }
                      }
      ];
}

- (void)stopAnimatingIndicators
{    
    self.indicatorLeft.transform = CGAffineTransformIdentity;
    self.indicatorRight.transform = CGAffineTransformIdentity;

    [CATransaction begin];
    [self.finishingIndicator.layer removeAllAnimations];
    [self.indicatorLeft.layer removeAllAnimations];
    [self.indicatorRight.layer removeAllAnimations];
    [CATransaction commit];

    self.finishingIndicator.alpha = 0.0;

    [self resetIndicatorsPosition];
}

- (void)resetIndicatorsPosition
{
    CGRect indicatorLeftFrame = self.indicatorLeft.frame;
    CGRect indicatorRightFrame = self.indicatorRight.frame;
    indicatorLeftFrame.origin.x = LEFT_INDICATOR_X_OFFSET;
    indicatorRightFrame.origin.x = RIGHT_INDICATOR_X_OFFSET;
    self.indicatorLeft.frame = indicatorLeftFrame;
    self.indicatorRight.frame = indicatorRightFrame;
}

1 个答案:

答案 0 :(得分:0)

执行以下操作时是否收到编译器错误或警告:

indicatorLeftFrame.origin.x = LEFT_INDICATOR_X_OFFSET;
indicatorRightFrame.origin.x = RIGHT_INDICATOR_X_OFFSET;

我的印象是你无法设置CGRect这样的组件。当我尝试时,我肯定会遇到编译器错误并且构建不起作用,所以我甚至不确定如何构建。我认为你必须制作一个新的CGRect

indicatorLeftFrame = CGRectMake(LEFT_INDICATOR_X_OFFSET, 
                                indicatorLeftFrame.origin.y,
                                indicatorLeftFrame.size.width,
                                indicatorLeftFrame.size.height);
indicatorRightFrame = CGRectMake(RIGHT_INDICATOR_X_OFFSET, 
                                 indicatorRightFrame.origin.y,
                                 indicatorRightFrame.size.width,
                                 indicatorRightFrame.size.height);

如果是这种情况(即帧起源未正确重置),那么我可以看到您的问题可能如何发生。请告诉我这是否有助于评论。