Как отменить блочную анимацию UIView?

86

Я просмотрел множество SO-материалов и ссылок Apple, но все еще не могу решить свою проблему.

Что я имею:

  1. Экран с подключенными к ним 2 UIImageViewс и 2 UIButtonс
  2. 2 вида анимации:
    1. Увеличение и уменьшение масштаба каждого изображения, одно за другим, только один раз в viewDidLoad
    2. При нажатии кнопки (настраиваемая кнопка, скрытая «внутри» каждой из них UIImageView) запускается соответствующая анимация UIImageView- только одна, а не обе - (также масштабируется вверх, затем вниз).
    3. Когда я пишу для iOS4 +, мне говорят использовать блочную анимацию!

Что мне нужно:

Как мне отменить запущенную анимацию? Мне все-таки удалось отменить, кроме последнего ...: /

Вот мой фрагмент кода:

[UIImageView animateWithDuration:2.0 
                               delay:0.1 
                             options:UIViewAnimationOptionAllowUserInteraction 
                          animations:^{
        isAnimating = YES;
        self.bigLetter.transform = CGAffineTransformScale(self.bigLetter.transform, 2.0, 2.0);
    } completion:^(BOOL finished){
        if(! finished) return;
        [UIImageView animateWithDuration:2.0 
                                   delay:0.0 
                                 options:UIViewAnimationOptionAllowUserInteraction 
                              animations:^{
            self.bigLetter.transform = CGAffineTransformScale(self.bigLetter.transform, 0.5, 0.5);
        } completion:^(BOOL finished){
            if(! finished) return;
            [UIImageView animateWithDuration:2.0 
                                       delay:0.0 
                                     options:UIViewAnimationOptionAllowUserInteraction 
                                  animations:^{
                self.smallLetter.transform = CGAffineTransformScale(self.smallLetter.transform, 2.0, 2.0);
            } completion:^(BOOL finished){
                if(! finished) return;
                [UIImageView animateWithDuration:2.0 
                                           delay:0.0 
                                         options:UIViewAnimationOptionAllowUserInteraction 
                                      animations:^{
                    self.smallLetter.transform = CGAffineTransformScale(self.smallLetter.transform, 0.5, 0.5);
                }
                                      completion:^(BOOL finished){
                                          if (!finished) return;
                                          //block letter buttons
                                          [self.bigLetterButton setUserInteractionEnabled:YES];
                                          [self.smallLetterButton setUserInteractionEnabled:YES];
                                          //NSLog(@"vieDidLoad animations finished");
                                      }];
            }];
        }];
    }];

Как-то smallLetter UIImageViewне работает должным образом, потому что при нажатии (через кнопку) bigLetterанимация отменяется правильно ...

РЕДАКТИРОВАТЬ: Я использовал это решение, но все еще проблема с уменьшением масштаба smallLetter UIImageView- вообще не отменять ... решение

EDIT2: я добавил это в начале следующих / предыдущих методов:

- (void)stopAnimation:(UIImageView*)source {
    [UIView animateWithDuration:0.01
                          delay:0.0 
                        options:(UIViewAnimationOptionBeginFromCurrentState | UIViewAnimationOptionAllowUserInteraction)
                     animations:^ {
                         source.transform = CGAffineTransformIdentity;
                     }
                     completion:NULL
     ];
}

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

Рейстлин
источник
Эй, я думаю, что ответ Хари Кунвара должен быть принят сейчас.
marczellm
В наши дни вы должны использовать UIViewPropertyAnimator - это тоже намного проще.
Fattie

Ответы:

151

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

[view.layer removeAllAnimations];

(Вам нужно будет импортировать платформу QuartzCore для вызова методов на view.layer).

Если вы хотите остановить конкретную анимацию, а не все анимации, лучше всего использовать явно CAAnimations, а не вспомогательные методы анимации UIView, тогда у вас будет более детальный контроль и вы сможете останавливать анимацию явно по имени.

Документацию Apple Core Animation можно найти здесь:

https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/CoreAnimation_guide/CreatingBasicAnimations/CreatingBasicAnimations.html

Ник Локвуд
источник
10
Просто хочу добавить, по моему собственному наблюдению, последующий animateWithDuration больше не работает после вызова removeAllAnimations. Это сделано для разбивки на страницы и подтягивания для обновления элементов управления, возможно, кто-то другой заметит что-то другое. В итоге я использую CABasicAnimation и вызываю [myView.layer removeAnimationForKey: @ "animationKey"];
Чжан
Спасибо за совет @Nick - просто предупреждаю, что ссылка больше не поддерживается, попробуйте вместо этого: developer.apple.com/library/ios/documentation/Cocoa/Conceptual/…
trdavidson
52

Для iOS 10 используйте UIViewPropertyAnimator для анимации. Он предоставляет методы для запуска, остановки и приостановки анимации UIView.

 let animator = UIViewPropertyAnimator(duration: 2.0, curve: .easeOut){
        self.view.alpha = 0.0
 }
 // Call this to start animation.
 animator.startAnimation()

 // Call this to stop animation.
 animator.stopAnimation(true)
Хари Кунвар
источник
3

Я бы добавил к ответу Ника, что следующая идея будет очень удобной, чтобы сделать removeAllAnimations гладкой.

[view.layer removeAllAnimations];
[UIView transitionWithView:self.redView
                  duration:1.0f options:UIViewAnimationOptionTransitionCrossDissolve animations:^{
                      [view.layer displayIfNeeded];
                  } completion:nil];
Гастон Морикс
источник
0

Вы можете попробовать это (в Swift):

UIView.setAnimationsEnabled(false)
UIView.setAnimationsEnabled(true)

Примечание: при необходимости вы можете поместить код между этими двумя вызовами, например:

UIView.setAnimationsEnabled(false)
aview.layer.removeAllAnimations() // remove layer based animations e.g. aview.layer.opacity
UIView.setAnimationsEnabled(true)
iAmcR
источник