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