I have an UIImageView
with an image. Now I have a completely new image (graphic file), and want to display that in this UIImageView
. If I just set
myImageView.image = newImage;
the new image is visible immediately. Not animatable.
I want it to nicely fade into the new image. I thought maybe there's a better solution than just creating a new UIImageView
on top of that and blending with animation?
This question is related to
ios
iphone
animation
uiimageview
uiimage
Swift 5 extension:
extension UIImageView{
func setImage(_ image: UIImage?, animated: Bool = true) {
let duration = animated ? 0.3 : 0.0
UIView.transition(with: self, duration: duration, options: .transitionCrossDissolve, animations: {
self.image = image
}, completion: nil)
}
}
There are a few different approaches here: UIAnimations to my recollection it sounds like your challenge.
Edit: too lazy of me:)
In the post, I was referring to this method:
[newView setFrame:CGRectMake( 0.0f, 480.0f, 320.0f, 480.0f)]; //notice this is OFF screen!
[UIView beginAnimations:@"animateTableView" context:nil];
[UIView setAnimationDuration:0.4];
[newView setFrame:CGRectMake( 0.0f, 0.0f, 320.0f, 480.0f)]; //notice this is ON screen!
[UIView commitAnimations];
But instead of animation the frame, you animate the alpha:
[newView setAlpha:0.0]; // set it to zero so it is all gone.
[UIView beginAnimations:@"animateTableView" context:nil];
[UIView setAnimationDuration:0.4];
[newView setAlpha:0.5]; //this will change the newView alpha from its previous zero value to 0.5f
[UIView commitAnimations];
Try this:
_imageView.image = image;
[_imageView.layer addAnimation:[CATransition animation] forKey:kCATransition];
Vladimir's answer is perfect, but anyone like me who is looking for swift solution
This Solution is Worked for swift version 4.2
var i = 0
func animation(){
let name = (i % 2 == 0) ? "1.png" : "2.png"
myImageView.image = UIImage.init(named: name)
let transition: CATransition = CATransition.init()
transition.duration = 1.0
transition.timingFunction = CAMediaTimingFunction.init(name: .easeInEaseOut)
transition.type = .fade
myImageView.layer.add(transition, forKey: nil)
i += 1
}
You can call this method from anywhere. It will change the image to next one(image) with animation.
For Swift Version 4.0 Use bellow solution
var i = 0
func animationVersion4(){
let name = (i % 2 == 0) ? "1.png" : "2.png"
uiImage.image = UIImage.init(named: name)
let transition: CATransition = CATransition.init()
transition.duration = 1.0
transition.timingFunction = CAMediaTimingFunction.init(name: kCAMediaTimingFunctionEaseInEaseOut)
transition.type = kCATransitionFade
uiImage.layer.add(transition, forKey: nil)
i += 1
}
[UIView transitionWithView:textFieldimageView
duration:0.2f
options:UIViewAnimationOptionTransitionCrossDissolve
animations:^{
imageView.image = newImage;
} completion:nil];
is another possibility
In the words of Michael Scott, keep it simple stupid. Here is a simple way to do this in Swift 3 and Swift 4:
UIView.transition(with: imageView,
duration: 0.75,
options: .transitionCrossDissolve,
animations: { self.imageView.image = toImage },
completion: nil)
Why not try this.
NSArray *animationFrames = [NSArray arrayWithObjects:
[UIImage imageWithName:@"image1.png"],
[UIImage imageWithName:@"image2.png"],
nil];
UIImageView *animatedImageView = [[UIImageView alloc] init];
animatedImageView.animationImages = animationsFrame;
[animatedImageView setAnimationRepeatCount:1];
[animatedImageView startAnimating];
A swift version:
let animationsFrames = [UIImage(named: "image1.png"), UIImage(named: "image2.png")]
let animatedImageView = UIImageView()
animatedImageView.animationImages = animationsFrames
animatedImageView.animationRepeatCount = 1
animatedImageView.startAnimating()
Here is one example in Swift that will first cross dissolve a new image and then add a bouncy animation:
var selected: Bool {
willSet(selected) {
let expandTransform:CGAffineTransform = CGAffineTransformMakeScale(1.15, 1.15);
if (!self.selected && selected) {
UIView.transitionWithView(self.imageView,
duration:0.1,
options: UIViewAnimationOptions.TransitionCrossDissolve,
animations: {
self.imageView.image = SNStockCellSelectionAccessoryViewImage(selected)
self.imageView.transform = expandTransform
},
completion: {(finished: Bool) in
UIView.animateWithDuration(0.4,
delay:0.0,
usingSpringWithDamping:0.40,
initialSpringVelocity:0.2,
options:UIViewAnimationOptions.CurveEaseOut,
animations: {
self.imageView.transform = CGAffineTransformInvert(expandTransform)
}, completion:nil)
})
}
}
}
var imageView:UIImageView
If imageView
is correctly added to the view as a subview, toggling between selected = false
to selected = true
should swap the image with a bouncy animation. SNStockCellSelectionAccessoryViewImage
just returns a different image based on the current selection state, see below:
private let SNStockCellSelectionAccessoryViewPlusIconSelected:UIImage = UIImage(named:"PlusIconSelected")!
private let SNStockCellSelectionAccessoryViewPlusIcon:UIImage = UIImage(named:"PlusIcon")!
private func SNStockCellSelectionAccessoryViewImage(selected:Bool) -> UIImage {
return selected ? SNStockCellSelectionAccessoryViewPlusIconSelected : SNStockCellSelectionAccessoryViewPlusIcon
}
The GIF example below is a bit slowed down, the actual animation happens faster:
As of iOS 5 this one is far more easy:
[newView setAlpha:0.0];
[UIView animateWithDuration:0.4 animations:^{
[newView setAlpha:0.5];
}];
With Swift 3
extension UIImageView{
var imageWithFade:UIImage?{
get{
return self.image
}
set{
UIView.transition(with: self,
duration: 0.5, options: .transitionCrossDissolve, animations: {
self.image = newValue
}, completion: nil)
}
}
}
Usage:
myImageView.imageWithFade = myImage
Code:
var fadeAnim:CABasicAnimation = CABasicAnimation(keyPath: "contents");
fadeAnim.fromValue = firstImage;
fadeAnim.toValue = secondImage;
fadeAnim.duration = 0.8; //smoothest value
imageView.layer.addAnimation(fadeAnim, forKey: "contents");
imageView.image = secondImage;
Example:
Fun, More Verbose Solution: (Toggling on a tap)
let fadeAnim:CABasicAnimation = CABasicAnimation(keyPath: "contents");
switch imageView.image {
case firstImage?:
fadeAnim.fromValue = firstImage;
fadeAnim.toValue = secondImage;
imageView.image = secondImage;
default:
fadeAnim.fromValue = secondImage;
fadeAnim.toValue = firstImage;
imageView.image = firstImage;
}
fadeAnim.duration = 0.8;
imageView.layer.addAnimation(fadeAnim, forKey: "contents");
Swift 5:
When deal with collectionView. Reloading only 1 item or several items with animation. I try some different animation options when changing cell image, no difference, so I don't indicate animation name here.
UIView.animate(withDuration: 1.0) { [weak self] in
guard let self = self else { return print("gotchya!") }
self.collectionView.reloadItems(at: [indexPath])
}
CABasicAnimation* fadeAnim = [CABasicAnimation animationWithKeyPath:@"contents"];
fadeAnim.fromValue = (__bridge id)imageView.image.CGImage;
fadeAnim.toValue = (__bridge id)[UIImage imageNamed:@"newImage.png"].CGImage;
fadeAnim.duration = 2.0;
[imageView.layer addAnimation:fadeAnim forKey:@"contents"];
imageView.layer.contents = (__bridge id)[UIImage imageNamed:@"newImage.png"].CGImage;
Swift 4 This is just awesome
self.imgViewPreview.transform = CGAffineTransform(scaleX: 0, y: 0)
UIView.animate(withDuration: 1, delay: 0, usingSpringWithDamping: 0.3, initialSpringVelocity: 0, options: .curveEaseOut, animations: {
self.imgViewPreview.image = newImage
self.imgViewPreview.transform = .identity
}, completion: nil)
Source: Stackoverflow.com