Comment faire un crossfade entre 2 images sur iPhone en utilisant Core Animation

Je le fais pour apprendre à travailler avec les propriétés animables de Core Animation sur iPhone (pas pour apprendre à fondre les images, en soi).

La lecture de questions similaires sur SO m’amène à croire que cela peut être fait en animant la propriété .contents du calque de UIImageView comme suit :

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"]; 

Ai-je mal compris ou est-ce que ce n’est pas possible?

Mise à jour: le code ci-dessus produit un UIImageView vide. Quand je change cette ligne:

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

… Je peux voir l’image maintenant, mais elle ne s’affiche pas, elle apparaît juste instantanément.

Vous étiez presque là.

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

Notez que l’animation est indépendante des valeurs / contenus réels de UIImageView. Par conséquent, vous devrez

 self.imageView.image = image2; 

… pour définir le résultat final de votre image.

J’ai trouvé ça quelque part – ça marche très bien.

Rapide

 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++; }]; 

}

Solution rapide

 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"); 

Ma suggestion serait d’utiliser juste deux UIImageView s les uns sur les autres. L’un en haut a l’image1, et en bas l’image2:

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

Cela va disparaître entre les deux images chaque fois que vous l’appelez. Si vous voulez simplement faire un seul fondu et supprimer la première image une fois que vous avez terminé:

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

Modifier:

Si vous cherchez une raison pour laquelle votre code ne fonctionne pas, c’est parce que vous définissez simplement la propriété sur la nouvelle image, puis vous ajoutez une animation inutile. CABasicAnimation a le fromValue et le toValue qui doivent être définis, puis ajoute cette animation au calque, et cela devrait faire l’animation. Ne définissez pas le contenu manuellement.