chevi99
chevi99

Reputation: 143

How do i keep on rotating an image until a response from a server in swift

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

Answers (3)

Victor Apeland
Victor Apeland

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

Duncan C
Duncan C

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

Razib Mollick
Razib Mollick

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

Related Questions