Остановить анимацию UIView с автореверсом/бесконечным повтором с помощью блока BOOL/завершения

Я настраиваю следующий метод UIView animateWithDuration: с намерением установить мой animationOn BOOL в другом месте программы, чтобы отменить этот бесконечный зацикленный повтор. У меня сложилось впечатление, что блок completion будет вызываться каждый раз, когда цикл анимации заканчивается, но, похоже, это не так.

Вызывается ли блок completion когда-либо в повторяющейся анимации? И если нет, есть ли другой способ остановить эту анимацию вне этого метода?

- (void) animateFirst: (UIButton *) button
{
    button.transform = CGAffineTransformMakeScale(1.1, 1.1);
    [UIView animateWithDuration: 0.4
                          delay: 0.0
                        options: UIViewAnimationOptionCurveEaseOut | UIViewAnimationOptionAutoreverse | UIViewAnimationOptionRepeat
                     animations: ^{
                         button.transform = CGAffineTransformIdentity;
                     } completion: ^(BOOL finished){
                         if (!animationOn) {
                             [UIView setAnimationRepeatCount: 0];
                         }
    }];
}

person Luke    schedule 21.12.2012    source источник


Ответы (4)


Блок завершения будет вызываться только тогда, когда анимация прерывается. Например, он вызывается, когда приложение переходит в фоновый режим и снова возвращается на передний план (через многозадачность). В этом случае анимация останавливается. Вы должны перезапустить анимацию, когда это произойдет.

Чтобы остановить анимацию, вы можете удалить ее из слоя представления:

[button.layer removeAllAnimations];
person Tom van Zummeren    schedule 21.12.2012
comment
Боюсь, это не сработало. Анимация все еще продолжается после применения изменения в преобразовании. (Я установил .transform на CGAffineTransformMakeScale(1.0, 1.0)). - person Luke; 21.12.2012
comment
Я нашел кое-что еще, что может сработать. Я обновил свой ответ. Вы можете это попробовать? - person Tom van Zummeren; 21.12.2012
comment
О, ты сам это понял :) Спасибо, что все равно принял мой ответ. - person Tom van Zummeren; 21.12.2012
comment
Ваше появилось почти сразу, как только я нажал «Добавить» на своем, так что я подумал, что это означает, что вы вводили его первым ;) - person Luke; 21.12.2012
comment
@TomvanZummeren Но это удалит каждую анимацию.... что, если у вас есть несколько блоков анимации, и вы хотите остановить только один из блоков анимации.... - person Supertecnoboff; 08.07.2015

Старый, но еще один вариант.

Вы также можете настроить другую анимацию, которая не повторяется в том же представлении, таким образом, вы также можете захватить ее в текущем состоянии и вернуть в исходное состояние с помощью параметра UIViewAnimationOptionBeginFromCurrentState. Ваш блок завершения также называется.

-(void)someEventSoStop
{
    button.transform = CGAffineTransformMakeScale(1.0, 1.0);
    [UIView animateWithDuration: 0.4
                          delay: 0.0
                        options: UIViewAnimationOptionCurveEaseOut | UIViewAnimationOptionBeginFromCurrentState
                     animations: ^{
                         button.transform = CGAffineTransformIdentity;
                     } completion: ^(BOOL finished){

                     }];
}
person Recycled Steel    schedule 26.02.2015
comment
Это более приятный подход, чем другое решение, поскольку он плавно возвращает анимацию к идентичности. - person Nikolozi; 11.01.2016

Я решил проблему, позвонив [button.layer removeAllAnimations].

person Luke    schedule 21.12.2012
comment
Я устал от этого, но это не работает для меня. Откуда в вашем коде вы вызываете этот метод? - person Supertecnoboff; 08.07.2015

Согласно документации ссылки на класс View: если вы использовали какой-либо из методов класса, таких как animateWithDuration:delay:options:animations:completion:, если для длительности установлено отрицательное значение или 0, изменения вносятся без выполнения анимации. поэтому я сделал что-то вроде этого, чтобы остановить бесконечную анимацию:

[UIView animateWithDuration:0.0 animations:^{
      button.layer.affineTransform = CGAffineTransformIdentity;
  }];

Я думаю, что это лучше, чем удалять все анимации из слоя, как в предложенном ответе. Обратите внимание, что это применимо ко всем другим методам анимации класса в классе UIView.

person Wael Showair    schedule 21.01.2016
comment
Это не сработало для меня. Мне пришлось вызвать removeAllAnimations. - person Mike Taverne; 22.04.2017