1
\$\begingroup\$

I have an array of UIImages that I animating using UIImageView, and creates an effect of wave.
the user have plus and minus button and can control the wave plus will make the wave animate faster.

enter image description here

But, when I change the animation duration of the UIImageView the animation stopped and I cannot continue with the stopped position. Only from start and the animation stopped in the middle. Also I cannot get the current present frame / start the animation from specific frame.

So I tried to find a solution for this problem by animation only one every time. But I feel that there are to many things happened in many threads.

Is there anything I can do to optimize my code?

class ViewController: UIViewController {

    @IBOutlet weak var imageView: UIImageView!

    var run = true
    var onComplete : (()->Void)?
    var time : Double = 3

    override func viewDidLoad() {
        super.viewDidLoad()

        imageView.animationImages = animationImages
        imageView.animationRepeatCount = 1

    }

    @IBAction func plusAction(_ sender: Any) {
        self.time -= 0.5
        self.onComplete = { [weak self] in
            if self?.run == false {return}
            self?.animate(secs: self?.time ?? 2)
            self?.run = false
        }
    }


    @IBAction func minusAction(_ sender: Any) {
        self.time += 0.5
        self.onComplete = { [weak self] in
            if self?.run == false {return}
            self?.animate(secs: self?.time ?? 2)
            self?.run = false
        }
    }

    @IBAction func stopAction(_ sender: Any) {
        run = false
        onComplete = nil
    }

    @IBAction func startAction(_ sender: Any) {
        animate(secs: self.time ?? 3)
        run = true
    }

    func animate(secs : Double){

        startAnimate(with: secs) { [weak self] in
            self?.onComplete?()
            if self?.run == false{
                self?.run = true
                return
            }
            self?.animate(secs: secs)

        }
    }

    func startAnimate(with duration : Double, onFinish : @escaping ()->Void){
        DispatchQueue.main.async { [weak self] in
            self?.imageView.animationDuration = duration
            self?.imageView.startAnimating()
            DispatchQueue.global().asyncAfter(deadline: .now() + duration) {
                onFinish()
            }
        }
    }
}
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.