How to Animate the Change of Image in an Uiimageview

How to animate the change of image in an UIImageView?

I am not sure if you can animate UIViews with fade effect as it seems all supported view transitions are defined in UIViewAnimationTransition enumeration. Fading effect can be achieved using CoreAnimation. Sample example for this approach:

#import 
...
imageView.image = [UIImage imageNamed:(i % 2) ? @"3.jpg" : @"4.jpg"];

CATransition *transition = [CATransition animation];
transition.duration = 1.0f;
transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
transition.type = kCATransitionFade;

[imageView.layer addAnimation:transition forKey:nil];

UIImageView transition between different images with animation

How can you do it?

you will need:

  1. A timer
  2. A counter
  3. An array of for holding image names

    var images:[String] = []

    var timer = Timer()

    var photoCount:Int = 0

in viewDidLoad i did this for initialization.

images = ["1","2","3"]
imageView.image = UIImage.init(named: "1")
timer = Timer.scheduledTimer(timeInterval: 2.0, target: self, selector: #selector(onTransition), userInfo: nil, repeats: true)

And the magic method for doing this is below:

func onTransition() {
if (photoCount < images.count - 1){
photoCount = photoCount + 1;
}else{
photoCount = 0;
}

UIView.transition(with: self.imageView, duration: 2.0, options: .transitionCrossDissolve, animations: {
self.imageView.image = UIImage.init(named: self.images[self.photoCount])
}, completion: nil)
}

Don't forget to pull your imageView referrence outlet. :)

   @IBOutlet weak var imageView: UIImageView!

Animate images in uiimageview

To download images from web service:

NSData *imageData = [NSData dataWithContentsOfURL:"*Url from web service*"];
UIImage *imageOne = [UIImage imageWithData:imageData];

likely download all images from web service and create an array like:

NSArray *imagesArray = [NSArray arrayWithObjects:imageOne...........,nil];

and use with little modification:

UIImageView* animatedImageView = [[UIImageView alloc] initWithFrame:self.view.bounds];
animatedImageView.animationImages = imagesArray;
animatedImageView.animationDuration = 1.0f;
animatedImageView.animationRepeatCount = 0;
[animatedImageView startAnimating];
[self.view addSubview: animatedImageView];

Fade/dissolve when changing UIImageView's image

Edit: there is a better solution from @algal below.

Another way to do this is by using predefined CAAnimation transitions:

CATransition *transition = [CATransition animation];
transition.duration = 0.25;
transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
transition.type = kCATransitionFade;
transition.delegate = self;
[self.view.layer addAnimation:transition forKey:nil];
view1.hidden = YES;
view2.hidden = NO;

See the View Transitions example project from Apple: https://developer.apple.com/library/content/samplecode/ViewTransitions/Introduction/Intro.html#//apple_ref/doc/uid/DTS40007411

Swift: change UIImageView image midway during animation

You should chain the two animations, each rotating with pi/2.

imageView.layer.anchorPoint = CGPoint(x: 0, y: 0.5)

var transform = CATransform3DIdentity
transform.m34 = -0.001
imageView.layer.transform = transform
UIView.animate(withDuration: 1.0, animations:
{
self.imageView.layer.transform = CATransform3DRotate(transform, .pi/2, 0, 1, 0)
self.imageViewCenterConstraintX.constant = 0
})
{
(bCompleted) in
if (bCompleted)
{
self.imageView?.layer.transform = CATransform3DRotate(transform, .pi/2, 0, 1, 0)
}

UIView.animate(withDuration: 1.0, animations:
{
self.imageView.layer.transform = CATransform3DRotate(transform, .pi*0.999, 0, 1, 0)
self.imageView.image = UIImage.init(named:"anotherImage")
},
completion:
{
(bFinished) in
//Whatever
})
}

Animate the CHANGE of UIImageView only one image

I think you can find your answer on this

How do I animate a set of UIImages backward inside UIImageVIew - swift - programmatically

I suggest we override the startAnimating() method. This way we can provide our own logic of the animation and decide what the next frame should be.

We'll create a frameTimer that will replace the image of the UIImageView every equal fraction of the animationDuration. It'll iterate over the images array forwards and backwards until stopped with the stopAnimating() method.

class BoomerangImageView: UIImageView {
// MARK: Overrides
override func startAnimating() {
guard let frames = animationImages, frames.count > 1 else {
return
}
image = frames.first

let timePerFrame = animationDuration / Double(frames.count)
let timer = Timer(fire: Date(timeIntervalSinceNow: timePerFrame),
interval: timePerFrame,
repeats: true) { [weak self] _ in
self?.changeFrame()
}
RunLoop.current.add(timer, forMode: .common)
frameTimer = timer
}

override func stopAnimating() {
frameTimer?.invalidate()
frameTimer = nil
currentFrameIndex = 0
}

// MARK: Private
private var frameTimer: Timer?
private var isAnimatingForward = true

private var currentFrameIndex = 0 {
didSet {
if let frames = animationImages,
currentFrameIndex >= 0,
currentFrameIndex < frames.count {
image = frames[currentFrameIndex]
}
}
}

private func changeFrame() {
guard let frames = animationImages, frames.count > 1 else {
stopAnimating()
return
}

let canAnimateForward = currentFrameIndex < frames.count - 1
let canAnimateBackward = currentFrameIndex > 0
isAnimatingForward = (isAnimatingForward && canAnimateForward) || (!isAnimatingForward && !canAnimateBackward)
currentFrameIndex += isAnimatingForward ? 1 : -1
}
}

Then in your view controller, you run the animation just like you planned:

class ViewController: UIViewController {
@IBOutlet weak var imageView: BoomerangImageView!

let frames: [UIImage] = [
// your images here
]

override func viewDidLoad() {
super.viewDidLoad()
imageView.animationImages = frames
imageView.animationDuration = 2
imageView.startAnimating()
}
}

It should look something like this:

boomerang demo



Related Topics



Leave a reply



Submit