Приостановка анимации CALayer с анимацией с задержкой - PullRequest
8 голосов
/ 21 марта 2012

У меня есть набор вложенных UIView анимаций (на 2 или 3 уровня в определенное время), которые я хотел бы иметь возможность приостановить и возобновить.Некоторые из этих анимаций используют -animateWithDuration:animations:completion:, в то время как другие используют -animateWithDuration:delay:options:animations:completion:, чтобы задержать выполнение блока анимации.

Я прочитал и реализовал Технические вопросы и ответы QA1673 о приостановке всех анимаций в слоедерево, но я столкнулся с проблемой с анимациями, которые используют параметр задержки.Я могу приостановить и возобновить анимацию просто отлично, но когда анимация возобновляется, кажется, что у любого анимационного блока, с которым связана задержка, задержка увеличивается на количество времени, в течение которого дерево слоя было приостановлено.Так, например, если один из блоков имеет задержку в 1 секунду, а дерево слоев было приостановлено на 3 секунды, анимация задерживается на 4 секунды после возобновления.Я предполагаю, что это как-то связано со свойством beginTime?Любая помощь будет оценена.

// Pause and Resume methods, right from the technical Q&A
- (void)pauseAnimationsOnLayer:(CALayer *)layer
{
    CFTimeInterval pausedTime = [layer convertTime:CACurrentMediaTime() fromLayer:nil];
    layer.speed = 0.0;
    layer.timeOffset = pausedTime;
}

- (void)resumeAnimationsOnLayer:(CALayer *)layer
{
    CFTimeInterval pausedTime = [layer timeOffset];
    layer.speed = 1.0;
    layer.timeOffset = 0.0;
    layer.beginTime = 0;
    CFTimeInterval timeSincePause = [layer convertTime:CACurrentMediaTime() fromLayer:nil] - pausedTime;
    layer.beginTime = timeSincePause;
}

// Chained animations
- (void)animateNextPopup
{
    [UIView animateWithDuration:kRFPVictorySequenceStatePopupDuration
                     animations:^{
                         [_currentStateImageView setHidden:NO];
                         [_currentStateImageView setTransform:CGAffineTransformIdentity];

                     }
                     completion:^(BOOL finished) {
                         [UIView animateWithDuration:kRFPVictorySequenceStateSlideOffDuration
                                               delay:kRFPVictorySequenceStateVoteDelay
                                             options:UIViewAnimationOptionCurveEaseInOut
                                          animations:^{
                                              if (winnerIsDem) {
                                                  [_currentStateImageView setFrame:CGRectMake(-_currentStateImageView.frame.size.width, 
                                                                                              _currentStateImageView.frame.origin.y, 
                                                                                              _currentStateImageView.frame.size.width, 
                                                                                              _currentStateImageView.frame.size.height)];
                                              }
                                              else {
                                                  [_currentStateImageView setFrame:CGRectMake(1024, 
                                                                                              _currentStateImageView.frame.origin.y, 
                                                                                              _currentStateImageView.frame.size.width, 
                                                                                              _currentStateImageView.frame.size.height)];
                                              }
                                          }
                                          completion:^(BOOL finished) {
                                              // Do some stuff
                                          }
                          ];
                     }
     ];
}

Ответы [ 2 ]

0 голосов
/ 23 мая 2012

Я нашел решение проблемы!Вы должны сбросить значение self.layer.beginTime на ноль в блоке завершения ваших анимаций.

например

[UIView animateWithDuration:element.duration 
                      delay:element.delay 
                    options:UIViewAnimationOptionCurveLinear
                 animations:^{
                      // Animate properties here!
                     }
                 } completion:^(BOOL finished){
                              // Reset BeginTime all the time
                              // So, in case a pause took place the delay values are valid again!
                         **self.layer.beginTime = 0.0f;**
                 }];

Остальная часть кода паузы / возобновления остается точно такой же.

Лучший!

0 голосов
/ 30 марта 2012

Я предлагаю другой подход.

Блоки анимации просты в реализации, но полезны, только если вам не нужен контроль над вашей анимацией.

В противном случае вам следует использовать таймерсоздайте свою собственную анимацию вручную.

[NSTimer scheduledTimerWithTimeInterval:0.1
                                 target:self
                               selector:@selector(timerFired)
                               userInfo:nil
                                repeats:YES];

- (void)timerFired
{
    if (isPaused) {
        // Do nothing
    } else {
        // Animate
    }
}

- (IBAction)pauseTapped:(id)sender
{
    if (isPaused) {
        isPaused = NO;
    } else {
        isPaused = YES;
    }
}

isPaused - это флаг, управляющий состоянием вашей анимации.

...