Як скасувати анімацію на основі блоку 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анімація скасовується належним чином ...

EDIT: Я використовував це рішення, але все ще маю проблему зі зменшенням масштабу 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).

Якщо ви хочете зупинити певну анімацію, а не всі анімації, найкраще використовувати явно CAA анімації, а не допоміжні методи анімації 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)
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.