Bagaimana cara membatalkan animasi berbasis blok UIView?

86

Saya telah mencari banyak barang SO dan referensi Apple, tetapi masih tidak dapat mengelola masalah saya.

Apa yang saya punya:

  1. Sebuah layar dengan 2 UIImageViewdetik dan 2 UIButtondetik terhubung dengannya
  2. 2 jenis animasi:
    1. Meningkatkan dan menurunkan skala setiap gambar, satu demi satu, hanya sekali viewDidLoad
    2. Ketika sebuah tombol ditekan (tombol kustom tersembunyi 'di dalam' masing-masing UIImageView) itu memicu animasi yang sesuai UIImageView–hanya satu, tidak keduanya– (juga skala naik, lalu turun).
    3. Saat saya menulis untuk iOS4 +, saya diberitahu untuk menggunakan animasi berbasis blok!

Apa yang saya butuhkan:

Bagaimana cara membatalkan animasi yang sedang berjalan? Aku sudah berhasil membatalkan semuanya kecuali yang terakhir ...: /

Ini cuplikan kode saya:

[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");
                                      }];
            }];
        }];
    }];

Entah bagaimana smallLetter UIImageViewini tidak berfungsi dengan baik, karena ketika ditekan (melalui tombol) bigLettermembatalkan animasi dengan benar ...

EDIT: Saya telah menggunakan solusi ini, tetapi masih mengalami masalah dengan memperkecil smallLetter UIImageView- tidak membatalkan sama sekali ... solusi

EDIT2: Saya telah menambahkan ini di awal metode berikutnya / sebelumnya:

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

masalah tetap ...: / tidak tahu bagaimana menghentikan animasi terakhir untuk huruf dalam rantai animasi

raistlin
sumber
Hei saya pikir jawaban Hari Kunwar harus diterima sekarang.
marczellm
Hari-hari ini Anda harus menggunakan UIViewPropertyAnimator - ini juga jauh lebih mudah.
Fattie

Jawaban:

151

Anda dapat menghentikan semua animasi pada tampilan dengan memanggil:

[view.layer removeAllAnimations];

(Anda harus mengimpor kerangka QuartzCore untuk memanggil metode di view.layer).

Jika Anda ingin menghentikan animasi tertentu, tidak semua animasi, taruhan terbaik Anda adalah menggunakan CAAnimations secara eksplisit daripada metode pembantu animasi UIView, maka Anda akan memiliki kontrol yang lebih terperinci dan dapat menghentikan animasi secara eksplisit berdasarkan nama.

Dokumentasi Apple Core Animation dapat ditemukan di sini:

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

Nick Lockwood
sumber
10
Hanya ingin menambahkan, dalam pengamatan saya sendiri, animateWithDuration berikutnya tidak berfungsi lagi setelah memanggil removeAllAnimations. Ini untuk melakukan paginasi dan tarik untuk menyegarkan kontrol, mungkin orang lain mungkin mengamati sesuatu yang berbeda. Saya akhirnya menggunakan CABasicAnimation dan memanggil [myView.layer removeAnimationForKey: @ "animationKey"];
Zhang
Terima kasih atas tip @Nick - pemberitahuan bahwa tautan tampaknya tidak lagi didukung, coba yang ini sebagai gantinya: developer.apple.com/library/ios/documentation/Cocoa/Conceptual/…
trdavidson
setelah view.layer.removeAllAnimations () tambahkan tampilan animasi lagi tidak berfungsi
Bunthoeun
52

Untuk iOS 10 gunakan UIViewPropertyAnimator untuk membuat animasi. Ini menyediakan metode untuk memulai, menghentikan, dan menjeda animasi 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)
Hari Kunwar
sumber
3

Saya akan menambahkan jawaban Nick bahwa untuk membuat removeAllAnimations ide selanjutnya menjadi sangat berguna.

[view.layer removeAllAnimations];
[UIView transitionWithView:self.redView
                  duration:1.0f options:UIViewAnimationOptionTransitionCrossDissolve animations:^{
                      [view.layer displayIfNeeded];
                  } completion:nil];
Gaston Morixe
sumber
0

Anda dapat mencoba ini (di Swift):

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

Catatan: Anda dapat meletakkan kode di antara kedua panggilan tersebut jika perlu, misalnya:

UIView.setAnimationsEnabled(false)
aview.layer.removeAllAnimations() // remove layer based animations e.g. aview.layer.opacity
UIView.setAnimationsEnabled(true)
iAmcR
sumber