turn animation 180 degrees in swift - swift

I am using a curl up animation when swiping up, which makes a card fly away to the top - it works fine. I'd like to use the same animation, but to swipe down, so that the card flies away down. I guess I'd have to somehow turn the swipe up animation 180 degrees. Is that possible?
let views = (frontView: self.frontView, backView: self.frontView)
// set a transition style
let transitionOptions = UIViewAnimationOptions.TransitionCurlUp
UIView.transitionWithView(self.flashCardView, duration: 0.5, options: transitionOptions, animations: {
views.frontView.removeFromSuperview()
self.flashCardView.addSubview(views.frontView)
}, completion: { finished in
// any code entered here will be applied
})

The UIViewAnimationOptions struct has another option that will solve this for you:
let transitionOptions = UIViewAnimationOptions.TransitionCurlDown

Related

Setting the image on UIImageView changes the animation

I have a UIImageView that I wish to animate at the click of a button. But before the animation, I set its image. However, this image-setting messes up the animation. When I comment out the image-set, the animation works as expected.
var busFrame = self.newBusView.frame
let sourceFrame = self.buttonA.superview?.convert(self.buttonA.frame.origin, to: nil)
busFrame.origin.y = sourceFrame!.y
busFrame.origin.x = sourceFrame!.x
self.newBusView.frame = busFrame
//the following line messes up the animation
// self.newBusView.image = UIImage(named: "back_blue")
UIView.animate(withDuration: 2.0, delay: 0.3, options: .curveEaseOut, animations: {
busFrame = self.newBusView.frame
let desstinationFrame = self.buttonD.superview?.convert(self.buttonD.frame.origin, to: nil)
busFrame.origin.y = desstinationFrame!.y
busFrame.origin.x = desstinationFrame!.x
self.newBusView.frame = busFrame
}, completion: { finished in
print("Done!")
//same thing happening here
//self.newBusView.image = UIImage(named: "Background 1")
})
Also note that the buttons are in separate Stack views (hence the need for superview?.convert)
UPDATE:
So it was noticed that whenever I have a button.setImage() the positions go wrong (Even if the button has nothing to do with the animation). But instead of setImage, if I use button.imageView.image = something, then it has no side effects on animations. What is happening?
Expected:
Actual:
As we do not know the "expected" animation, I could not repeat the problem that you have. When I set same image again in the commented line, I get the same animation.
It may be about the area that the image covers. New image's ratio may be different than the default, therefore you see different animation although view's animation is same. You actually animate the view. Hence, you should focus on frames.
I believe that as #musakokcen mentioned your image have different size.
Try to use:
yourImageView.layer.masksToBounds = yes

How can i interact with views while they keep animating in UIKit (swift 4)?

I have a set of shapes (UIViews), that can be moved on the screen using a UIPanGestureRecognizer, and that are supposed to wiggle continuously and forever after the user triggers the animation. But I want them to keep wiggling, even while the user picks one up and moves it.
What is practically happening is that when the user picks up a shape, it stops animating, and when he puts it back down, it doesn't even restart the animation.
Here's some code for the context:
func wiggle() {
UIView.animate(withDuration: 0.15, options: [.repeat, .autoreverse, .allowUserInteraction], animation: {
self.view.subviews.forEach { $0.transform = CGAffineTransform(rotationAngle: CGFloat.pi/8) })
}
func pickUpShape() {
[.....]
shape.transform = CGAffineTransform(scaleX: 2, scaleY: 2)
shape.layer.shadowOpacity = 0.7
}
func moveShape() {
//apply UIPanGestureRecognizer
}
func placeShape() {
[.....]
shape.transform = .identity
shape.layer.shadowOpacity = 0
}
What I want it to do is, if the user triggers the wiggle action, and picks a shape up and moves it, i want the shape to continue wiggling under the user's finger, and after he places it down.

iOS UIButton in Navigation bar disappears after performing transform animation

I'm trying to animate transform from '+' button to 'X' button by rotating it on click.
Everything works great when I'm using standard button on UIView. I'm using following code:
UIView.animateWithDuration(2.0, delay: 0.0, options: .CurveEaseOut, animations: {
let transform = CGAffineTransformMakeRotation(CGFloat(M_PI_4))
self.navigationPlusButton.transform = transform
}, completion: nil)
The problem occurs when I try to achieve the same with button in navigation bar.
Looks like button height is resized to 0 before the rotation and I don't know how to fix navigation button size since there are no constraints definitions. Note storyboard
and for constraints
Note: Second approach using CABasicAnimation rotated button nicely but it returned it to initial state immediately after animation ends. I would like to stay 'X' until I click again.
let rotateAnimation = CABasicAnimation(keyPath: "transform.rotation")
rotateAnimation.fromValue = 0.0
rotateAnimation.toValue = CGFloat(M_PI_4)
rotateAnimation.duration = 2.0
self.navigationPlusButton.layer.addAnimation(rotateAnimation, forKey: nil)
How it works so easily outside the navigation bar and it is so hard to do it on navigation bar? I can't find the solution. Please help
try following lines to your code, it will solve your problem.
rotateAnimation.fillMode = kCAFillModeForwards
rotateAnimation.removedOnCompletion = false
Try this line on the CABasicAnimation:
rotateAnimation.removedOnCompletion = false
It may solve your problem.

Implementing basic animations with tvOS

I'm hoping someone may be able to help me understand why my tvOS animations are not running.
In my code I have a function like this:
func testAnimation() {
clockLabel.alpha = 0.0
UIView.animateWithDuration(1.0, animations: {
self.clockLabel.alpha = 1.0
})
}
I am calling testAnimation() from within my viewDidLoad(), but no animation ever seems to happen.
I've tested with a few different types of animations, from things like position to opacity, but it seems that no animation ever actually runs in the Simulator.
At this time, my app does not have a focus. All I'm trying to do is load a blank UIView with a label in the middle that fades in.
You're trying to animate your UILabel before it has been displayed. Move your animation from viewDidLoad() to viewDidAppear().
I can confirm this behaviour as this happens for me as well. What I did was setting a delay of 0.1 (afterDelay:), and it is "good enough"
On the other hand, what DID actually work was setting a transform for my views. E.g. (objc though):
CGAffineTransform scaleTransform = CGAffineTransformMakeScale(0.5,0.5);
[UIView animateWithDuration: 0.5 animations:^{
_myView.transform = scaleTransform;
} completion: nil]
Maybe it's a bug in tvOS
Try using UIView Animation, like this (Swift):
clockLabel.alpha = 0
UIView.animateWithDuration(0.5, delay: 0.0, options: .Linear, animations: {
self.clockLabel.alpha = 1.0
}, completion: { finished in
// you may add some code here to make another action right after the animation end, or just delete this comment :)
})
This works on our side.

remove UITextView from SpriteKit app with animation

I have a UITextView object in my Swift/SpriteKit program but while the transition from SpriteKit scene to SpriteKit scene works well, I can't get the UITextView to animate in a similar way.
For the scene transition, I use:
let transition = SKTransition.flipVerticalWithDuration(1)
let newScene = GameScene(size: self.frame.size)
view?.presentScene(newScene, transition: transition)
And to remove the UITextView, I use
myUITextView.removeFromSuperview()
Any ideas how I can get the textView to flip on the vertical axis as well, and at the same time as the scene change?
Update:
I realised this might be too difficult to do, so I changed it to this...
let transition = SKTransition.revealWithDirection(.Right, duration: 1.0)
let newScene = GameScene(size: self.frame.size)
newScene.scaleMode = .AspectFill
let options = UIViewKeyframeAnimationOptions.CalculationModeLinear
UIView.animateKeyframesWithDuration(1.0, delay: 0.0, options: options, animations: {
UIView.addKeyframeWithRelativeStartTime(0, relativeDuration: 1/2, animations: {
self.myUITextView.transform = CGAffineTransformMakeTranslation(300, 0)
})
}, completion: {finished in
self.myUITextView.removeFromSuperview()
})
view?.presentScene(newScene, transition: transition)
The exact timing between the scene transition and the UITextView animation needs some tuning but this basically works, except for a new problem.
The new scene I'm transitioning to also has a UITextView. This appears on top of the one I'm animating away (like pulling a card out from behind the deck). I understand why this is happening, the presentScene function is calling the new scene, and with it, the declaration of the new UITextView. Because SpriteKit and UIKit don't work well together, this is being placed on top of the older UITextView I'm trying to remove. Any ideas how I can achieve this animation with the old scene's UITextView being kept on top?
Update2: I've done a little experiment with the following commands:
let transitionOptions = UIViewAnimationOptions.TransitionFlipFromLeft
var views : (frontView: UIView, backView: UIView)
views = (frontView: self.myUITextView, backView: self.UITextView)
UIView.transitionFromView(views.frontView, toView: views.backView, duration: 1.0, options: transitionOptions, completion: nil)
When I did this, I expected the myUITextView to flip from the left, but to my surprise the entire SKView flipped in the way I was looking for as well. The only problem is the toView is pointing back onto the same scene (so it flips back onto oldScene) and I want to go to newScene. Any ideas how to point towards the new scene or open it behind the old scene?