Home > OS >  Swift UIKit - Sequential animation function
Swift UIKit - Sequential animation function

Time:01-15

I have a func UIView.animate (2 imageViews, up/down, pulsating 4 and 2 times sequentially), which is forking fine. Problem is that i need to run this func sequentially, all animations executed -> next lap of execution -> N lap of execution for my needs (it can be 5 or it can be 25 etc). How can i do it?

    func upDown() {
        runButton.isEnabled = false

        UIView.animate(
            withDuration: 0.5,
            delay: 0,
            options: [.autoreverse, .repeat]) {
                UIView.modifyAnimations(withRepeatCount: 4, autoreverses: true) {
                    self.arrowDownImageView.transform = CGAffineTransform(scaleX: 1.3, y: 1.3)
                    self.arrowDownImageView.tintColor = .green
                    self.downLabel.backgroundColor = .green
                }
            } completion: { _ in
                self.arrowDownImageView.transform = .identity
                self.downLabel.transform  = .identity
                self.downLabel.backgroundColor = .black
                self.arrowDownImageView.tintColor = .black
                
                UIView.animate(
                    withDuration: 0.5,
                    delay: 0,
                    options: [.autoreverse, .repeat]) {
                        UIView.modifyAnimations(withRepeatCount: 2, autoreverses: true) {
                            self.arrowUpImageView.transform = CGAffineTransform(scaleX: 1.3, y: 1.3)

                            self.arrowUpImageView.tintColor = .blue
                            self.upLabel.backgroundColor = .blue
                        }
                    } completion: { _ in
                        self.arrowUpImageView.transform = .identity
                        self.upLabel.transform = .identity
                        self.upLabel.backgroundColor = .black
                        self.arrowUpImageView.tintColor = .black
                        
                        self.runButton.isEnabled = true
                    }
            }
    }

I tried to call my func upDown() through other UIView.animate ( .modifyAnimations) func (executed 1 time only), call it with for-in-loop (also wrong, like i clicked X-times on a button). Should i rebuild it with some other method, not UIView.animate? In this case which one? Pods are forbidden in my case. I'm planning (need) to place my upDown() inside a new func to run it sequentially. Any other ideas? Any other methods? Thanks!

CodePudding user response:

It sounds like you want your upDown function called multiple times. You can add a count parameter to upDown. Then in the final completion handler you can call upDown with the next smaller number. When the count gets to zero you can exit.

Here's your upDown method with only two lines added plus the new default parameter. Added the guard at the beginning and the recursive call at the very end in the last completion block.

func upDown(count: Int = 1) {
    guard count > 0 else { return } // stop when we get to zero

    runButton.isEnabled = false

    UIView.animate(
        withDuration: 0.5,
        delay: 0,
        options: [.autoreverse, .repeat]) {
            UIView.modifyAnimations(withRepeatCount: 4, autoreverses: true) {
                self.arrowDownImageView.transform = CGAffineTransform(scaleX: 1.3, y: 1.3)
                self.arrowDownImageView.tintColor = .green
                self.downLabel.backgroundColor = .green
            }
        } completion: { _ in
            self.arrowDownImageView.transform = .identity
            self.downLabel.transform  = .identity
            self.downLabel.backgroundColor = .black
            self.arrowDownImageView.tintColor = .black
            
            UIView.animate(
                withDuration: 0.5,
                delay: 0,
                options: [.autoreverse, .repeat]) {
                    UIView.modifyAnimations(withRepeatCount: 2, autoreverses: true) {
                        self.arrowUpImageView.transform = CGAffineTransform(scaleX: 1.3, y: 1.3)

                        self.arrowUpImageView.tintColor = .blue
                        self.upLabel.backgroundColor = .blue
                    }
                } completion: { _ in
                    self.arrowUpImageView.transform = .identity
                    self.upLabel.transform = .identity
                    self.upLabel.backgroundColor = .black
                    self.arrowUpImageView.tintColor = .black
                    
                    self.runButton.isEnabled = true

                    upDown(count - 1) // Run it again
                }
        }
}

With those few changes you can call upDown() if you only want it to run once or you can call it as upDown(count: 5) if you want it to run 5 times (or whatever number you pass in).

  • Related