i have animation that starts after view appeares and i need to stop it by tap, but animation doesnt stop
code:
Property
private var isAnimating = true
Animation (every 0.1 seconds shows new image)
func animateImage() {
UIImageView.transition(with: self.imageView, duration: 0.1, options: .transitionCrossDissolve) {
self.imageView.setImage(imageUrl: self.imagesArray[self.nextImage])
} completion: { _ [weak self] in
if self.nextImage != self.imagesCount - 1 {
self.nextImage = 1
} else {
self.nextImage = 0
}
self.animateImage()
}
}
UITapGestureRecognizer
let tap = UITapGestureRecognizer(target: self, action: #selector(tapOnImage))
self.addGestureRecognizer(tap)
Action for tap
@objc func tapOnImage(sender: UITapGestureRecognizer) {
if isAnimating {
imageView.stopAnimating()
} else {
imageView.startAnimating()
}
isAnimating.toggle()
}
CodePudding user response:
In the completion handler, you call self.animateImage()
again to form a loop. If you call this conditionally on isAnimating
, then the loop will "break" once isAnimating
is false:
completion: { _ [weak self] in
guard let `self` = self else { return }
if self.nextImage != self.imagesCount - 1 {
self.nextImage = 1
} else {
self.nextImage = 0
}
// notice this condition
if self.isAnimating {
self.animateImage()
}
}
Also note that imageView.startAnimating()
starts animating using the imageView.animationImages
, not the animation you have created here with UIImageView.animate
, which is just the same as UIView.animate
. So you only need the single line of
isAnimating.toggle()
in tapOnImage
.
Since you seem to want to restart the animation when isAnimating
is set to true, you should call animateImage
in its didSet
:
private var isAnimating = true {
didSet {
if isAnimating {
animateImage()
}
}
}