Pausing and restarting animations - swift

I'm working on a test that uses swift UIKit dynamics to animate a ball across the screen. I want to add a button in the top left of the screen, that when pressed, pauses the screen just how it is, then when pressed again, resumes the animation. If anyone has any suggestions on how to go about doing this that would be much appreciated. Thank you

The simplest thing to do is to set the speed of the layer of a superview that contains all views being animated to 0:
self.view.layer.speed = 0
Then set it back to 1.0 when you want the animation to continue.
(It isn't obvious that layers have a speed property. It is there because they conform to the CAMediaTiming protocol.)

Related

Animating an UIButton on an UIScrollView

I'm having problems animating my button in my scrollview. Basically what I'm doing is moving the button down the y-axis when the button is pressed down and moving it back to it's original position once the press has stopped. My code itself works just fine and does exactly what it is meant to do. Oddly enough, it only does so on a regular View. On a scrollView, it only moves it down after a short delay after it is pressed and the animation is very choppy. I know that there's nothing wrong with my code and that's why I'm so confused. Does anybody have an idea on how to fix this? Any help would be greatly appreciated!
Not sure how to make what you want work, but I am pretty sure the "choppy" behaviour is a result of the UIScrollView touch being recognized and activating what it is meant to activate (i.e pan gesture). One idea that comes to mind is to disable scrolling when this action is performed.

How can I pause a currently running animation?

I have a Core Animation running and want to pause it when a button is pressed. So there is a method -pauseAnimation. When the animation is paused, I want the animated view to stay in the state as it currently was while animating. i.e. if a view moves from top left to bottom right, and somewhere in the middle the animation is paused, the view should stay in the middle.
Is there a way to do this?
as far as i can remember there is an setAnimationsEnabled=NO option, but that doesn't work when the animation runs, right?
You can pause layer animations by setting the speed of the animation to zero, see How to pause the animation of a layer tree.
You can do this by disabling animations and then setting the model layers' values to the presentation layers' values (for all properties that define your animation).
eg. layer.transform = layer.presentationLayer.transform;
Resuming the animation = re-enable animations and animate from current positions to the desired final positions (you might have to adjust curves, etc to get something acceptable).

iPhone Flip Transition - Can I get notified at the half way point

I have a single UIView for drawing any one of a set of items. That is, my one UIView subclass can be told to draw a square, circle, or triangle for example.
I'd like to have a transition to flip that view so that the UIView draws a different shape at the half way point, so it looks like I'm transitioning to a different view, but really I'm just redrawing the single view at the half way point of the transition.
Is there a way to do this, without resorting to using two different UIViews and swapping them out in the animation block? It would be a bit clumsy for me to rejig what I have to use the swap mechanism.
Ideally all I need is some callback or notification that the animation is at the half way point, and then I can redraw the view with the new shape then.
Thanks for any help!
Even if you did know the midpoint of your flip animation, I don't believe redrawing the content of the view mid-animation would do anything. I think that the contents of the view's layer are cached at the beginning of the animation and don't change as the animation proceeds. Also, your view would end up inverted, left to right, at the end of the animation if you didn't have another view behind it.
If you wish to do this as a custom animation, you could break this into two halves using something like Mike Lee's Lemur Flip implementation that I describe in this answer. After the first half of the animation, you could redraw the view's content and complete the animation, ending up back where you started.
However, to me it seems more clumsy to not switch views in response to the transition. It certainly will take a lot more code to do.
you can try to do smth like this. For example, your animationDuration property is set to 2.0f. so, the half way point is 1 second, so you can use
[self performSelector:#selector(yourCallbackMethod) withObject:nil afterDelay:1.0f];
The only way I know of that you could do this is to re-create the animation using Core Animation and then monitor the animation in the presentationLayer using a timer. There is no KVO available in Core Animation Layers so you have to monitor it explicitly.
In other words, it's probably not worth it. I suggest you think of a different way to solve your problem.

Is there an way to pause an Core Animation and resume it at some time later?

I have several Core Animation's going on at the same time. They all have an context and an animation id, where the context is the object that's beeing animated (UIImageView objects). I would like to pause them, so that the animation just stops temporarily, and then when some things are done, resume it to complete it. These things happen only on very fast scroll movements in an UIScrollView. I want to improve performance by stopping all ongoing animations but not the one that makes the scroll view scroll. I have implemented an custom animation of the contentOffset for that scroll view.
You can pause layer animations by setting the speed of the animation to zero, see How to pause the animation of a layer tree.
To anyone who comes searching, this is how you pause and resume animations:
https://developer.apple.com/library/archive/qa/qa1673/_index.html
The only way I have gotten around this is the following.
For each view you wish to stop animating:
Set the view's frame to the presentation layer
Remove all animations from that view
Perform your scroll
Recalculate animations
Add new animations to the view
I know it isn't what you want to hear, but it isn't as bad as it sounds. A good way to track the views you want to stop is to give them a predetermined tag.
To remove animations:
[myView.layer removeAllAnimations]
[myView.layer removeAnimationForKey:#"theAnimationKey"]
The Core Animation Programming Guide has a section on Customizing the Timing of an Animation which includes a section on Pausing and Resuming Animations.

Is there a way to swap layers or views in the middle of a CAKeyframeAnimation?

I am running a keyFrame animation to move and flip a playing card view using CAKeyframeAnimation. is there any way to swap the cardFront and cardBack layers during the animation? or am i taking the wrong approach here...
use a timer set to half the animation duration to execute cardBack.contents = cardFront.contents