запуск CABasicAnimation последовательно

Как я могу запустить одну CABasicAnimation после завершения работы другой? Другими словами, последовательно. Я добавил время начала второй анимации, но кажется, что вторая анимация не выполняется:

CABasicAnimation * appearance =[CABasicAnimation animationWithKeyPath:@"transform.translation.y"];
    appearance.duration = 0.5;
    appearance.fromValue = [NSNumber numberWithFloat:0];
    appearance.toValue = [NSNumber numberWithFloat:340];
    appearance.repeatCount = 1;
    appearance.fillMode = kCAFillModeForwards;
    appearance.removedOnCompletion = NO;
    [notif.layer addAnimation:appearance forKey:@"transform.translation.y"];



    CABasicAnimation * theAnimation=[CABasicAnimation animationWithKeyPath:@"transform.translation.y"];
    theAnimation.duration = 0.5;
    theAnimation.fromValue = [NSNumber numberWithFloat:0];
    theAnimation.toValue = [NSNumber numberWithFloat:10];
    theAnimation.repeatCount = 3;
    theAnimation.autoreverses = YES;
    theAnimation.fillMode = kCAFillModeForwards;
    theAnimation.removedOnCompletion = NO;
    theAnimation.beginTime = appearance.beginTime + appearance.duration;
    [notif.layer addAnimation:theAnimation forKey:@"transform.translation.y"];

Есть идеи, почему?


person adit    schedule 17.10.2011    source источник


Ответы (4)


Обновленный код, это сработает!

1-я анимация

CABasicAnimation * appearance =[CABasicAnimation animationWithKeyPath:@"transform.translation.y"];
    [appearance setValue:@"animation1" forKey:@"id"];
    appearance.delegate = self;
    [UIView setAnimationDidStopSelector:@selector(animationDidStop:finished:)];
    appearance.duration = 0.5;
    appearance.fromValue = [NSNumber numberWithFloat:0];
    appearance.toValue = [NSNumber numberWithFloat:340];
    appearance.repeatCount = 1;
    appearance.fillMode = kCAFillModeForwards;
    appearance.removedOnCompletion = NO;
    [notif.layer addAnimation:appearance forKey:@"transform.translation.y"];

2-я анимация:

    - (void)animationDidStop:(CAAnimation *)theAnimation2 finished:(BOOL)flag {
    if([[theAnimation2 valueForKey:@"id"] isEqual:@"animation1"]) {
    CABasicAnimation * theAnimation=[CABasicAnimation animationWithKeyPath:@"transform.translation.y"];
    theAnimation.duration = 0.5;
    theAnimation.fromValue = [NSNumber numberWithFloat:0];
    theAnimation.toValue = [NSNumber numberWithFloat:10];
    theAnimation.repeatCount = 3;
    theAnimation.autoreverses = YES;
    theAnimation.fillMode = kCAFillModeForwards;
    theAnimation.removedOnCompletion = NO;
    theAnimation.beginTime = appearance.beginTime + appearance.duration;
    [notif.layer addAnimation:theAnimation forKey:@"transform.translation.y"];
}

}

Вот как будет срабатывать вторая анимация после завершения первой.

person SimplyKiwi    schedule 17.10.2011
comment
это не сработало .. animationDidStop вызывалась бесконечно - person adit; 17.10.2011
comment
Если у вас есть цикл, уверены ли вы, что не установили делегата второй анимации таким образом, чтобы вторая анимация также вызывала animationDidStop? - person isaac; 17.10.2011
comment
если вы посмотрели на сам код, он не компилируется ... вы объявляете переменную theAnimation, в которой имя параметра функции также является theAnimation - person adit; 17.10.2011
comment
Упс, я исправил это выше, трудно увидеть, когда не использую Xcode! : / Также проголосуйте за мой ответ, если он вам нравится: P - person SimplyKiwi; 18.10.2011
comment
Работает отлично. Спасибо! Кстати, я написал µкатегорию на CABasicAnimation, чтобы перевернуть fromValue ‹--› toValue. - person ; 07.08.2014
comment
Сейчас 2016 год. Это все еще лучшее решение для последовательного выполнения анимации? - person durazno; 09.04.2016

Самое простое - настроить делегата для первой анимации и реализовать в этом объекте -animationDidStop:finished:. В этом методе отключите вторую анимацию.

person Chris Parker    schedule 17.10.2011

Причина, по которой ваша анимация не выполняется по плану, связана с тем, как вы закодировали и использовали Core Animation. Все основные анимации работают на графическом процессоре. CA infact очень хорошо справляется с несколькими вещами для оптимального рендеринга анимации.

Одним из его элементов является необработанная параллельная вычислительная мощность современных видеокарт, а другим является тот факт, что Core Animation может кэшировать содержимое CALayer на карте, так что вашему коду не нужно постоянно его перерисовывать. Это, кстати, одна из причин, по которой пользовательский интерфейс iPhone настолько быстр на относительно скромном оборудовании. Core Animation может автоматически использовать преимущества многоядерного компьютера Mac, поскольку дерево слоев отображается в отдельном потоке.

Последняя строка - imp. CA работают в отдельном потоке (а не в основном потоке). Итак, возвращаясь к вашей проблеме, у вас есть 2 блока CA, каждый из которых пытается оживить одно и то же transform.translation.y Оба одновременно! Как это будет работать?

Итак, чтобы решить эту проблему, либо сделайте -

  1. Кто-то предложил поставить задержку для второй анимации, чтобы после первой анимации вторая включалась только после завершения первой ОС.
  2. или Попробуйте сделать всю анимацию в одном блоке (опять же, как кто-то предложил).

Я просто хотел выделить теорию и аргументы в пользу того, как работает Core Animation. Надеюсь это поможет...

person Srikar Appalaraju    schedule 17.10.2011

Самый простой и чистый способ - использовать CAAnimationGroup. Взгляните на этот ответ - он мне помог.

Объединение анимаций основной анимации

person lobianco    schedule 18.06.2013
comment
CAAnimationGroup предназначен для одновременной, а не последовательной анимации, обычно для анимации нескольких свойств. - person ; 07.08.2014