Método de acceso después del acabado de la animación UIImageView

Tengo una serie de imágenes cargadas en un UIImageView que estoy animando a través de un ciclo. Después de que se hayan mostrado las imágenes, me gustaría @selector a @selector para descartar el controlador de vista actual. Las imágenes están animadas bien con este código:

 NSArray * imageArray = [[NSArray alloc] initWithObjects: [UIImage imageNamed:@"HowTo1.png"], [UIImage imageNamed:@"HowTo2.png"], nil]; UIImageView * instructions = [[UIImageView alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; instructions.animationImages = imageArray; [imageArray release]; instructions.animationDuration = 16.0; instructions.animationRepeatCount = 1; instructions.contentMode = UIViewContentModeBottomLeft; [instructions startAnimating]; [self.view addSubview:instructions]; [instructions release]; 

Después de los 16 segundos, me gustaría que se llame un método. Busqué en el método de clase setAnimationDidStopSelector: pero no puedo hacerlo funcionar con mi implementación de animación actual. ¿Alguna sugerencia?

Gracias.

Use performSelector:withObject:afterDelay: ::

 [self performSelector:@selector(animationDidFinish:) withObject:nil afterDelay:instructions.animationDuration]; 

o use dispatch_after :

 dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, instructions.animationDuration * NSEC_PER_SEC); dispatch_after(popTime, dispatch_get_main_queue(), ^(void){ [self animationDidFinish]; }); 

Puedes usar esta categoría UIImageView-AnimationCompletionBlock de forma sencilla

Y para la versión Swift : UIImageView-AnimationImagesCompletionBlock

Eche un vistazo al archivo ReadMe en esta clase.

Agrega los archivos UIImageView + AnimationCompletion.hy UIImageView + AnimationCompletion.m en el proyecto y los importa el archivo UIImageView + AnimationCompletion.h donde quieras utilizar esto.

Por ej.

 NSMutableArray *imagesArray = [[NSMutableArray alloc] init]; for(int i = 10001 ; i<= 10010 ; i++) [imagesArray addObject:[UIImage imageNamed:[NSString stringWithFormat:@"%d.png",i]]]; self.animatedImageView.animationImages = imagesArray; self.animatedImageView.animationDuration = 2.0f; self.animatedImageView.animationRepeatCount = 3; [self.animatedImageView startAnimatingWithCompletionBlock:^(BOOL success){ NSLog(@"Animation Completed",);}]; 

No hay forma de hacer esto precisamente con UIImageView. El uso de un retraso funcionará la mayor parte del tiempo, pero puede haber cierto retraso después del inicio. Se invoca a la animación antes de que ocurra la animación en la pantalla, por lo que no es precisa. En lugar de utilizar UIImageView para esta animación, intente utilizar CAKeyframeAnimation, que llamará a un método delegado cuando finalice la animación. Algo en esta línea:

 NSArray * imageArray = [[NSArray alloc] initWithObjects: (id)[UIImage imageNamed:@"HowTo1.png"].CGImage, (id)[UIImage imageNamed:@"HowTo2.png"].CGImage, nil]; UIImageView * instructions = [[UIImageView alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; //create animation CAKeyframeAnimation *anim = [CAKeyframeAnimation animation]; [anim setKeyPath:@"contents"]; [anim setValues:imageArray]; [anim setRepeatCount:1]; [anim setDuration:1]; anim.delegate = self; // delegate animationDidStop method will be called CALayer *myLayer = instructions.layer; [myLayer addAnimation:anim forKey:nil]; 

Luego solo implementa el método de delegado animationDidStop

Con este método, evita que los temporizadores se disparen mientras la imagen todavía está animando debido a la lenta carga de la imagen. Puede usar tanto performSelector: withObject: afterDelay: y GCD de esta manera:

 [self performSelector:@selector(didFinishAnimatingImageView:) withObject:imageView afterDelay:imageView.animationDuration]; 

/! \ self.imageView.animationDuration tiene que apostar configurado antes de startAnimating , de lo contrario será 0

Que si -(void)didFinishAnimatingImageView: crea una cola de fondo, realiza una comprobación en la propiedad isAnimating , luego ejecuta el rest en la cola principal

 - (void)didFinishAnimatingImageView:(UIImageView*)imageView { dispatch_queue_t backgroundQueue = dispatch_queue_create("com.yourcompany.yourapp.checkDidFinishAnimatingImageView", 0); dispatch_async(backgroundQueue, ^{ while (self.imageView.isAnimating) NSLog(@"Is animating... Waiting..."); dispatch_async(dispatch_get_main_queue(), ^{ /* All the rest... */ }); }); } 

Puede crear un temporizador para disparar después de la duración de su animación. La callback podría procesar su lógica que desea ejecutar después de que termine la animación. En su callback, asegúrese de verificar el estado de la animación [UIImageView isAnimating] en caso de que desee más tiempo para finalizar la animación.

Versión Swift creada a partir de GurPreet_Singh Respuesta (UIImageView + AnimationCompletion) No pude crear una extensión para UIImageView, pero creo que esto es lo suficientemente simple de usar.

 class AnimatedImageView: UIImageView, CAAnimationDelegate { var completion: ((_ completed: Bool) -> Void)? func startAnimate(completion: ((_ completed: Bool) -> Void)?) { self.completion = completion if let animationImages = animationImages { let cgImages = animationImages.map({ $0.cgImage as AnyObject }) let animation = CAKeyframeAnimation(keyPath: "contents") animation.values = cgImages animation.repeatCount = Float(self.animationRepeatCount) animation.duration = self.animationDuration animation.delegate = self self.layer.add(animation, forKey: nil) } else { self.completion?(false) } } func animationDidStop(_ anim: CAAnimation, finished flag: Bool) { completion?(flag) } } let imageView = AnimatedImageView(frame: CGRect(x: 50, y: 50, width: 200, height: 135)) imageView.image = images.first imageView.animationImages = images imageView.animationDuration = 2 imageView.animationRepeatCount = 1 view.addSubview(imageView) imageView.startAnimate { (completed) in print("animation is done \(completed)") imageView.image = images.last } 

en ImageView.m

 - (void) startAnimatingWithCompleted:(void (^)(void))completedHandler { if (!self.isAnimating) { [self startAnimating]; dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, self.animationDuration * NSEC_PER_SEC); dispatch_after(popTime, dispatch_get_main_queue(),completedHandler); }}