Cómo hacer crossfade entre 2 imágenes en iPhone usando Core Animation

Hago esto para aprender a trabajar con las propiedades animables de Core Animation en iPhone (no para aprender cómo hacer fundidos cruzados de imágenes, per se).

La lectura de preguntas similares en SO me lleva a creer que se puede hacer animando la propiedad .contents de la capa de UIImageView de la siguiente manera:

UIImage *image1 = [UIImage imageNamed:@"someImage1.png"]; UIImage *image2 = [UIImage imageNamed:@"someImage2.png"]; self.imageView.image = image1; [self.view addSubview:self.imageView]; CABasicAnimation *crossFade = [CABasicAnimation animationWithKeyPath:@"contents"]; crossFade.duration = 5.0; self.imageView.layer.contents = image2; [self.imageView.layer addAnimation:crossFade forKey:@"animateContents"]; 

¿Recibí un detalle incorrecto o esto no es posible?

Actualización: el código anterior produce un UIImageView en blanco. Cuando cambio esta línea:

 self.imageView.layer.contents = image2.CGImage; 

… Puedo ver la imagen ahora pero no se desvanece, simplemente aparece al instante.

Estabas casi allí.

 CABasicAnimation *crossFade = [CABasicAnimation animationWithKeyPath:@"contents"]; crossFade.duration = 5.0; crossFade.fromValue = image1.CGImage; crossFade.toValue = image2.CGImage; [self.imageView.layer addAnimation:crossFade forKey:@"animateContents"]; 

Tenga en cuenta que la animación es independiente de los valores / contenidos reales de UIImageView. Por lo tanto, necesitarás

 self.imageView.image = image2; 

… para establecer el resultado final de tu imagen.

Encontré esto en alguna parte, funciona genial.

Rápido

 UIView.transition(with: imageView, duration: 0.33, options: .transitionCrossDissolve, animations: { imageView.image = image }, completion: nil) 

Objc

 UIImage * toImage = [UIImage imageNamed:@"image.png"]; [UIView transitionWithView:self.view duration:0.33f options:UIViewAnimationOptionTransitionCrossDissolve animations:^{ self.imageview.image = toImage; } completion:NULL]; 
 extension UIImageView { func mySetImage(image:UIImage) { guard let currentImage = self.image where currentImage != image else { return } let animation = CATransition() animation.duration = 0.3 animation.type = kCATransitionFade layer.addAnimation(animation, forKey: "ImageFade") self.image = image } } 
 - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view from its nib. self.navigationController.navigationBarHidden=false; UIImage *img=[UIImage imageNamed:@"images.jpeg"]; imgview=[[UIImageView alloc]init]; imgview.frame=CGRectMake(30,90, img.size.width, img.size.height); [self.view addSubview:imgview]; [self animateImages]; } - (void)animateImages { static int count = 0; NSArray *animationImages = @[[UIImage imageNamed:@"images.jpeg"], [UIImage imageNamed:@"images (1).jpeg"]]; UIImage *image = [animationImages objectAtIndex:(count % [animationImages count])]; [UIView transitionWithView:imgview duration:2.0f // animation duration options:UIViewAnimationOptionTransitionCrossDissolve animations:^{ imgview.image = image; } completion:^(BOOL finished) { [self animateImages]; count++; }]; 

}

Solución en veloz

 let image1:UIImage = UIImage(named: "someImage1")!; let image2:UIImage = UIImage(named: "someImage2")!; let crossFade:CABasicAnimation = CABasicAnimation(keyPath: "contents"); crossFade.duration = 5.0; crossFade.fromValue = image1.CGImage; crossFade.toValue = image2.CGImage; imageView.layer.addAnimation(crossFade, forKey:"animateContents"); 

Mi sugerencia sería usar dos UIImageView s uno encima del otro. El que está en la parte superior tiene la imagen1, y en la parte inferior está la imagen2:

 - (void) crossfade { [UIView beginAnimations:nil context:nil]; [UIView setAnimationDuration:.5]; imageView1.alpha = !imageView1.alpha; [UIView commitAnimations]; } 

Eso se desvanecerá entre las dos imágenes cada vez que lo llame. Si solo quieres hacer un solo fundido y eliminar la primera imagen una vez que hayas terminado:

 - (void) crossfade { [UIView beginAnimations:nil context:nil]; [UIView setAnimationDuration:.5]; [UIView setAnimationDelegate:imageView1]; [UIView setAnimationDidStopSelector:@selector(removeFromSuperview)]; imageView1.alpha = 0 [UIView commitAnimations]; } 

Editar:

Si está buscando una razón por la que su código no funciona, es porque solo está configurando la propiedad a la nueva imagen y luego agrega una animación inútil. CABasicAnimation tiene los fromValue y toValue que se deben establecer, luego agrega esa animación a la capa y debería hacer la animación. No configure los contenidos manualmente.