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