how to do imageView.startAnimating() with completion in swift?
Add #selector()
and @objc
at last solution.
When the button is pressed you can call a function with a delay:
self.perform(#selector(afterAnimation), with: nil, afterDelay: imageView1.animationDuration)
Then stop the animation and add the last image of imageArray
to the imageView
in the afterAnimation
function:
@objc func afterAnimation() {
imageView1.stopAnimating()
imageView1.image = imageArray.last
}
UIImageView with completion handler
Please try the following:
// Create a Core Animation transaction and set its completion block
CATransaction.begin()
CATransaction.setCompletionBlock {
NSLog("Animation complete")
}
// create your animations as before
iv.animationImages = (0...40).map { UIImage(named: "loader_\($0)")! }
iv.animationDuration = 40 / 30
iv.animationRepeatCount = 1
iv.image = UIImage(named: "loader_40")
iv.startAnimating()
// Commit the transaction
CATransaction.commit()
Wrapping inside a Core Animation transaction should provide a completion block that will get called when the animation is complete.
Access Method After UIImageView Animation Finish
Use performSelector:withObject:afterDelay:
:
[self performSelector:@selector(animationDidFinish:) withObject:nil
afterDelay:instructions.animationDuration];
or 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];
});
How to use completion block for UIView.animate()?
The size is 0, 0. Transforming zero by any scale is still zero. I would advise you to not use transform at all, but rather just set the final frame
to be what you want.
E.g.,
let startFrame = CGRect(x: view.bounds.midX, y: view.bounds.midY, width: 0, height: 0)
let endFrame = view.bounds
let imageView = UIImageView(image: ...)
imageView.contentMode = .scaleAspectFill
view.addSubview(imageView)
imageView.frame = startFrame
UIView.animate(withDuration: 3, delay: 0, options: .curveEaseInOut) {
imageView.frame = endFrame
} completion: { _ in
// do something here
}
That yields:
By the way, the performSegue
probably should be inside a completion
closure of the inner animate
call.
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 <QuartzCore/QuartzCore.h>
...
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];
Navigate to New View Controller after Animation is Completed in Swift 3.0
Use DispatchQueue.main.asyncAfter
.
EDITED
Set Storyboard ID to SecondViewController.
Example #1:
...
imageView.animationRepeatCount = 1 // <-- here
imageView.startAnimating()
DispatchQueue.main.asyncAfter(deadline: .now() + imageView.animationDuration) {
let secondViewController = self.storyboard?.instantiateViewController(withIdentifier: "SecondViewController")
self.show(secondViewController, sender: nil)
}
Example #2:
...
imageView.animationRepeatCount = 1 // <-- here
imageView.startAnimating()
DispatchQueue.main.asyncAfter(deadline: .now() + 5.0) {
let secondViewController = self.storyboard?.instantiateViewController(withIdentifier: "SecondViewController")
self.show(secondViewController, sender: nil)
}
stop UIImageView.transition
In the completion handler, you call self.animateImage()
again to form a loop. If you call this conditionally on isAnimating
, then the loop will "break" once isAnimating
is false:
completion: { _ [weak self] in
guard let `self` = self else { return }
if self.nextImage != self.imagesCount - 1 {
self.nextImage += 1
} else {
self.nextImage = 0
}
// notice this condition
if self.isAnimating {
self.animateImage()
}
}
Also note that imageView.startAnimating()
starts animating using the imageView.animationImages
, not the animation you have created here with UIImageView.animate
, which is just the same as UIView.animate
. So you only need the single line of
isAnimating.toggle()
in tapOnImage
.
Since you seem to want to restart the animation when isAnimating
is set to true, you should call animateImage
in its didSet
:
private var isAnimating = true {
didSet {
if isAnimating {
animateImage()
}
}
}
Related Topics
Scenekit Ar Game Fps Getting Low and The Device Getting Hot with Use
Applying Impulses in Spritekit
Swift Casting Generic to Optional with a Nil Value Causes Fatalerror
Apple Mach-O Linker Error (Static, Not Ld)
Comma Automatically Being Added to Textfield in Swift
Macos App Sandboxing - Read Access to Referenced Files from Parsed Xml
Cast While Looping Over Dictionary in Swift
Idiomatic Way to Test Swift Optionals
How to Loop Over The Output of a Publisher with Combine
On Demand Resources "0 Asset Packs"
Testing a Class Which Preserves Its State in Private Variables
Access Each Header and Controls in The Tableview in Swift
Swiftui New App Lifecycle How to Connect The Facebook Sdk
Swift Loaditem Closure Not Running
How to Get a Full List of Running Processes
Dictionary Becomes Nil When Trying to Pass Back Cllocation Object to iOS App Extension