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
Related
I have a UIImageView.
I can either get it bouncing by using animate:
self.myImage.frame = CGRect(x: myImage.center.x, y: myImage.center.y, width: 50, height: 70)
UIView.animate(withDuration: 0.4, delay: 0, options: [.repeat, .autoreverse] , animations: {
self.myImage.frame = CGRect(x: self.myImage.center.x, y: self.myImage.center.y, width: 70, height: 80);
}) { (completed) in }
or, I can drag it by using panGestureRecogniser:
#IBAction func dragView(_ sender: UIPanGestureRecognizer) {
let translation = sender.translation(in: self.view)
if let viewToDrag = sender.view {
viewToDrag.center = CGPoint(x: viewToDrag.center.x + translation.x, y: viewToDrag.center.y + translation.y)
sender.setTranslation(.zero, in: viewToDrag)
}
How do I switch from first bouncing and then to dragging?
Add .allowUserInteraction to your options when setting up the animation
self.myImage.frame = CGRect(x: myImage.center.x, y: myImage.center.y, width: 50, height: 70)
UIView.animate(withDuration: 0.4, delay: 0, options: [.repeat, .autoreverse, .allowUserInteraction] , animations: {
self.myImage.frame = CGRect(x: self.myImage.center.x, y: self.myImage.center.y, width: 70, height: 80);
}) { (completed) in }
EDIT:
to break the bouncing animation loop use self.myImage.layer.removeAllAnimations() in the beginning state of the pan gesture like so:
#IBAction func dragView(_ sender: UIPanGestureRecognizer) {
let translation = sender.translation(in: self.view)
if let viewToDrag = sender.view {
if sender.state == .began {
viewToDrag.layer.removeAllAnimations()
}
viewToDrag.center = CGPoint(x: viewToDrag.center.x + translation.x, y: viewToDrag.center.y + translation.y)
sender.setTranslation(.zero, in: viewToDrag)
}
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)
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)
}
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)
})
}
}
I want to do drag and drop for UITextView via UIPanGestureRecognizer with auto aligning on center of the screen. For the first drag it works good, but if i try to do it again my drag start with init point of the UITextView. I don't know how to fix it.
First Drag
Second Drag
#objc func handlePan(gesture: UIPanGestureRecognizer) {
let translation = gesture.translation(in: nil)
switch gesture.state {
case .changed:
dragingText.transform = CGAffineTransform(translationX: translation.x, y: translation.y)
case .ended:
UIView.animate(withDuration: 1, delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: 1, options: .curveEaseOut, animations: {
self.dragingText.transform = CGAffineTransform(translationX: 0, y: translation.y)
}, completion: nil)
default:
()
}
}
CGAffine Transform is not necessary for your task. Try:
case .changed:
textview.center = CGPoint(x: textview.x + translation.x,
y: textview.y + translation.y )
Solved a problem
#objc func handlePan(gesture: UIPanGestureRecognizer) {
let translation = gesture.translation(in: nil)
switch gesture.state {
case .changed:
dragingText.center = CGPoint(x: dragingText.center.x + translation.x, y: dragingText.center.y + translation.y )
gesture.setTranslation(CGPoint.zero, in: nil)
case .ended:
let isInside = isInsideDragableAres()
if isInside.0 {
UIView.animate(withDuration: 0.7, delay: 0, usingSpringWithDamping: 0.4, initialSpringVelocity: 0.7, options: .curveEaseOut, animations: {
self.dragingText.center = CGPoint(x: self.view.center.x, y: self.dragingText.center.y + translation.y )
}, completion: nil)
}
else{
UIView.animate(withDuration: 0.7, delay: 0, usingSpringWithDamping: 0.4, initialSpringVelocity: 0.7, options: .curveEaseOut, animations: {
self.dragingText.center = CGPoint(x: self.view.center.x, y: isInside.1! )
}, completion: nil)
}
default:
()
}
}