Есть ли проблема с обновлением позиции CALayer во время паузы слоя? - PullRequest
6 голосов
/ 07 мая 2011

Есть ли проблема с чтением позиции презентации, пока она приостановлена?

Я пытаюсь приостановить и возобновить CALayer.Как только CALayer будет приостановлено, я хочу обновить позицию слоя с его текущей позицией представления.Когда я пытаюсь сделать это, слой слегка мигает, как только я возобновляю слой.

Это код, который я использую для приостановки и возобновления CALayer (на основе Технических вопросов и ответов QA1673 предоставлено Apple):

CFTimeInterval pausedTime;
void pauseLayer(CALayer *layer)
{
    pausedTime = [layer convertTime:CACurrentMediaTime() fromLayer:nil];
    layer.speed = 0.0;
    layer.timeOffset = pausedTime;
    layer.beginTime = 0;
//    layer.position = ((CALayer*)[layer presentationLayer]).position;
}
void resumeLayer(CALayer *layer)
{
    layer.speed = 1.0;
    layer.timeOffset = 0.0;
    layer.beginTime = 0.0;

    CFTimeInterval _elapsedTimeSincePaused = [layer convertTime:CACurrentMediaTime() fromLayer:nil] - pausedTime;
    layer.beginTime = _elapsedTimeSincePaused;
}

Если я раскомментирую layer.position = ((CALayer*)[layer presentationLayer]).position; in pauseLayer, слой мигает, когда я звоню resumeLayer.

Это мой код анимации:

- (void) startAnimation:(id)sender
{
    layer10Animation = [CABasicAnimation animationWithKeyPath:@"position.x"];
    layer10Animation.duration = 1;
    layer10Animation.toValue = [NSNumber numberWithInt:300];
    layer10Animation.fromValue = [NSNumber numberWithInt:20];
    layer10Animation.repeatCount = 100;
    layer10Animation.autoreverses = YES;

    [layer10 addAnimation:layer10Animation forKey:nil];
}

С уважением

1 Ответ

3 голосов
/ 02 ноября 2011

Нет проблем с обновлением позиции CALayer, пока она приостановлена.Естественно, однако, это даст мерцание, которое вы упоминаете.Это потому, что вы обновляете анимацию положения слоя в середине.

Не забывайте, что создание CABasicAnimation и добавление его к CALayer не изменяет настройки слоя.Он создает анимацию , используя слой, но не меняет слой.

Именно поэтому после завершения анимации вы увидите слой в том же положении, что и он.было раньше.

Из-за этого, если вы анимируете слой от A до B, если вы хотите, чтобы слой появлялся в B после завершения анимации, вам понадобится обратный вызов делегата:

- (void)animationDidStart:(CAAnimation *)theAnimation
{ 
    [CATransaction begin];
    [CATransaction setValue:(id)kCFBooleanTrue
                     forKey:kCATransactionDisableActions];
    myLayer.position = targetPosition;    
    [CATransaction commit];
}

Да, это animationDidStart.Если бы мы сделали это, используя animationDidStop, вы бы увидели еще одно мерцание.Слой будет находиться в конечной позиции анимации B, затем вы увидите его мерцание в точке A, а затем снова увидите его в точке B.

Используя animationDidStart, мы устанавливаем позицию набыть targetPosition, то есть B, потому что именно там мы хотим увидеть его по завершении.

Теперь, что касается QA1673 , то, что вы делаете с этим, устанавливает скорость анимации наноль, и получение временной отметки текущего CACurrentMediaTime().При возобновлении вы возвращаете скорость к нормальной и применяете любые смещения, возникающие во время паузы.

Все это кажется довольно запутанным, пока вы не освоитесь с ней.Могу ли я порекомендовать немного чтения и видео?

Определенно читайте Архитектура рендеринга базовой анимации .

Видео, которые настоятельно рекомендуется:

WWDC 2010 Sessions 424 и 425Основная анимация на практике, части 1 и 2

WWDC 2011 г. Сессия 421 Основные основы анимации

и

Видео для разработчиков Сессия 716Основные анимационные приемы для iPhone и Mac

...