简体   繁体   中英

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)
                            }
}

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

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()

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()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM