How do I stop an animation when tapped - swift

I'm making a tap game, and this is the button with the animation. It is very slow, and I want to speed it up so when the user taps, it will reset the animation and count the tap.
Currently, it is slow to the point that it will miss taps if tapped again while the animation is still going on.
#IBAction func slimeTap(_ sender: UIButton) {
tapCount += tapIncrease
checkLevel(tapCount)
UIView.animate(withDuration: 0.03, animations: {
//shrink
self.playSound()
sender.transform = CGAffineTransform(scaleX: 0.8, y: 0.8)
}, completion: {_ in
//change it back to how it was
//grow
UIView.animate(withDuration: 0.05, animations: {
sender.transform = CGAffineTransform(scaleX: 1, y: 1)
})
})
}

Try adding .layer.removeAllAnimations() to remove any existing animations on the layer, and .allowUserInteraction as an animation option to enable and register user tap events:
#IBAction func slimeTap(_ sender: UIButton) {
tapCount += tapIncrease
checkLevel(tapCount)
resizingView.layer.removeAllAnimations()
UIView.animate(withDuration: 0.3, delay: 0, options: [.allowUserInteraction], animations: {
self.playSound()
sender.transform = CGAffineTransform(scaleX: 0.8, y: 0.8)
}) { _ in
UIView.animate(withDuration: 0.5, delay: 0, options: [.allowUserInteraction], animations: {
sender.transform = CGAffineTransform(scaleX: 1, y: 1)
})
}
}

Related

CGAffineTransform(translationX: , y: ) will only move UIImage View to the right

I have two UIButtons for moving UImages left and right accordingly. The code for the both UIButtons is as follows,
#IBAction func MoveLeft(_ sender: Any) {
let yPosition1 = myslider.frame.origin.y
let yPosition2 = ImageView.frame.origin.y
let yPosition3 = ImageView2.frame.origin.y
UIView.animate(withDuration: 0.0, delay: 0.0, options: [], animations: {
self.myslider.transform = CGAffineTransform(translationX: -0.1, y: yPosition1)
self.ImageView.transform = CGAffineTransform(translationX: -0.1, y: yPosition2)
self.ImageView2.transform = CGAffineTransform(translationX: -0.1, y: yPosition3)
}, completion: nil)
}
#IBAction func MoveRight(_ sender: Any) {
let yPosition1 = myslider.frame.origin.y
let yPosition2 = ImageView.frame.origin.y
let yPosition3 = ImageView2.frame.origin.y
UIView.animate(withDuration: 0.0, delay: 0.0, options: [], animations: {
self.myslider.transform = CGAffineTransform(translationX: 0.1, y: yPosition1)
self.ImageView.transform = CGAffineTransform(translationX: 0.1, y: yPosition2)
self.ImageView2.transform = CGAffineTransform(translationX: 0.1, y: yPosition3)
}, completion: nil)
}
the values for the translation are opposite of each other so in theory the buttons should move the UIImages in different directions correct? Although when I run the and try using the "MoveLeft" UIButton the UIImages move in the same direction as if I was using the "MoveRight" UIButton. Any ideas on how to fix this issue would be greatly appreciated

Touch Labels That Keep Animating

I'm having an issue trying to touch a label that keeps animating because during the animation it becomes an image (set the animation on repeat). Is there a way to touch it during animation (I cant't use UITapGestureRecognizer) ?
func animatePro() {
UIView.animate(withDuration: 2, delay: 0, options: [.autoreverse, .repeat], animations: {
//1.5 times it's normal size
self.proLabel.transform = CGAffineTransform(scaleX: 1.5, y: 1.5)
}){ (finished) in
self.proLabel
.transform = CGAffineTransform.identity
}
}
func animateRev() {
UIView.animate(withDuration: 2, delay: 0, options: [.repeat], animations: {
//1.5 times it's normal size
self.revLabel.transform = CGAffineTransform(scaleX: 1.5, y: 1.5)
}){ (finished) in
UIView.animate(withDuration: 2, delay: 0, animations: {
self.revLabel.transform = CGAffineTransform.identity
})
}
}
Add allowUserInteraction
options: [.allowUserInteraction,.autoreverse, .repeat]

Swift move image from right to left than from left to right

I want to make an animation that move a background image from right to left than left to right.
I use this code but not works
UIView.animate(withDuration: 5, delay: 0, options: .repeat ,animations: { () -> Void in
imageView.transform = CGAffineTransform(translationX: -imageView.frame.width + self.view.bounds.width, y: 0)
UIView.animate(withDuration: 5, delay: 1, options: .repeat ,animations: { () -> Void in
imageView.transform = CGAffineTransform(translationX: +imageView.frame.width - self.view.bounds.width, y: 0)
})
})
I solved with this
UIView.animate(withDuration: 30.0, delay: 0, options: [.repeat, .autoreverse], animations: {
imageView.transform = CGAffineTransform(translationX: -imageView.frame.width + self.view.bounds.width, y: 0)
}, completion: nil)
Use the following code if you want to use the legacy animate(withDuration:animations:) API. However, you need to wait for the first animation to be finished - this means you have to use the completion block.
However, your value for translationX does not makes sense as well.
UIView.animate(withDuration: 1, animations: {
self.imageView.transform = CGAffineTransform(translationX: -self.imageView.frame.width, y: 0)
}) { _ in
UIView.animate(withDuration: 1) {
self.imageView.transform = CGAffineTransform.identity
}
}
I would strongly recommend having a look at the "new" way of doing Animations: UIViewPropertyAnimator(https://developer.apple.com/documentation/uikit/uiviewpropertyanimator)

Swift UIView Animate doesn't work properly

Slide up animation will be triggered when a button is clicked.
func animation_onClick(action: String) {
let up = CGAffineTransform(translationX: 0, y: -30)
myView.transform = CGAffineTransform(translationX: 0, y: 0)
UIView.animate(withDuration: 0.5, delay: 0.0, options: [], animations: {
self.myView.transform = up
}, completion: nil)
}
My code means when the function runs, myView’s position will be set to (0, 0) referring to its original position every time before it was set to (0, -30).
But when I run the app, I repeatedly click the button, somehow myView doesn't go back to its origin, it goes below where it should be. What I mean is it's not supposed to go below its origin.
See the gif below.
Try the following
func animation_onClick(action: String) {
myView.layer.removeAllAnimations()
myView.transform = .identity
UIView.animate(withDuration: 0.5, delay: 0.0, options: [], animations: {
self.myView.transform = CGAffineTransform(translationX: 0, y: -30)
}, completion: nil)
}

UIButton animation ignores target selector in Swift

I've added this animation code to the end of a function that is called when the button is pushed, but while the animation is happening, it ignores the set target selector until the animation is finished. The animation is very fast, but I'd like users to be able to press it rapidly.
let transforms: CGAffineTransform = .identity
mirroredButton.transform = transforms
UIView.animate(withDuration: 0.05, animations: {
mirroredButton.transform = transforms.scaledBy(x: 0.75, y: 0.75)
},
completion: { _ in
UIView.animate(withDuration: 0.1) {
mirroredButton.transform = transforms.scaledBy(x: 1.0, y: 1.0)
}
})
Update:
Using the answer, I updated my animation code as shown below. Both animation calls need options. The 2nd has a nil completion handler.
let transforms: CGAffineTransform = .identity
mirroredButton.transform = transforms
UIView.animate(withDuration: 0.05, delay: 0.0, options: .allowUserInteraction, animations: {
mirroredButton.transform = transforms.scaledBy(x: 0.75, y: 0.75)
},
completion: { _ in
UIView.animate(withDuration: 0.1, delay: 0.0, options: .allowUserInteraction, animations: {
mirroredButton.transform = transforms.scaledBy(x: 1.0, y: 1.0)
}, completion:nil)
})
User interaction is disabled for the duration of a view's animation. If it's critical that the user should interact with a view during an animation, you can pass in the option .allowUserInteraction, like so:
UIView.animate(withDuration: 1.0, delay: 0.0, options: .allowUserInteraction, animations: {
//animate here
})