Reputation: 143
I am making an async call whenever a button is clicked now I want an image which is like a refresh icon to be rotating or spinning until I get a response from my server. What i have now only rotates pi that's 180 and when the response arrives too the image doesn't reset. Have pasted my sample code below:
//When the update button is clicked
@objc func updateHome(){
UIView.animate(withDuration: 1) {
self.updateIcon.transform = CGAffineTransform(rotationAngle: .pi)
}
getBalances()
}
//Inside getBalances function
DispatchQueue.main.async {
if responseCode == 0 {
let today = self.getTodayString()
print("Time: \(today)")
UIView.animate(withDuration: 1) {
self.updateIcon.transform = CGAffineTransform(rotationAngle: .pi)
}
}
Upvotes: 0
Views: 1198
Reputation: 110
This code rotates your UIImageView
indefinitely using CABasicAnimation
:
let rotateAnimation = CABasicAnimation(keyPath: "transform.rotation")
rotateAnimation.fromValue = 0.0
rotateAnimation.toValue = CGFloat(.pi * 2.0)
rotateAnimation.duration = 1.0 // Change this to change how many seconds a rotation takes
rotateAnimation.repeatCount = Float.greatestFiniteMagnitude
updateIcon.layer.add(rotateAnimation, forKey: "rotate")
And when you get your signal from your server you can call
updateIcon.layer.removeAnimation(forKey: "rotate")
to stop the animation
Upvotes: 1
Reputation: 131418
One way you can handle this is to add an instance variable that tracks when the work is completed:
var finished: Bool = false
Then write a function that rotates the image and uses the completion handler to call itself to continue rotating:
func rotateImage() {
UIView.animate(withDuration: 1,
delay: 0.0,
options: .curveLinear
animations: {
self.updateIcon.transform = CGAffineTransform(rotationAngle: .pi)
},
completion: { completed in
if !self.finished {
self.rotateImage()
}
}
}
}
If you want to stop the animation instantly, you should set finished = true
and call updateIcon.layer.removeAllAnimations()
Upvotes: 0
Reputation: 5052
For continuous rotation, you can use CAKeyframeAnimation too like below.
@objc func updateHome() {
let animation = CAKeyframeAnimation(keyPath: "transform.rotation.z")
animation.duration = 1.0
animation.fillMode = kCAFillModeForwards
animation.repeatCount = .infinity
animation.values = [0, Double.pi/2, Double.pi, Double.pi*3/2, Double.pi*2]
let moments = [NSNumber(value: 0.0), NSNumber(value: 0.1),
NSNumber(value: 0.3), NSNumber(value: 0.8), NSNumber(value: 1.0)]
animation.keyTimes = moments
self.updateIcon.layer.add(animation, forKey: "rotate")
getBalances()
}
In your Async method (inside)DispatchQueue.main.async, you can stop like below. This will keep you to the original position of the image.
self.updateIcon.layer.removeAllAnimations()
Upvotes: 0