Animation end callback after adding points - highcharts

My chart is adding points to its series in certain interval using addPoint(). I've set its animation duration via chart.animation.duration - is there any way of calling my custom callback after animation is completed? I want to make it look more "live". I know about events.redraw(), however this is being fired on the beginning of the animation.

You can also catch redraw function (api.highcharts.com/highstock#chart.events.redraw) and use setTimeout() which will have the same time as animation time.

Related

How can I animate the movement of a view dynamically and smoothly without stopping - iOS Swift

I have a problem with animation as I want the same animation with different end points, to be called upon finishing the previous animation and to be executed smoothly without slight stop.
Let me elaborate with a sample code and comments.
Func animate()
{
Start animation(completionHandler: {
If condition is true
Repeat the animation and check after it finishes
}
}
but the problem with this code is that, between finishing the first animation and starting another one, there will be a split second stop which is not smooth movement. For example, I have a view on zero point to move with animation to point A (x:100,y:100), and then it will receive point B (x:500, y:900), after it reaches point A it will stop a split second then move to point B. Since the points are Dynamic, I cannot know if there is a new point or not, and if I did i will not know the coordinates beforehand, so I need to keep the logic dynamic and keeps the animation smooth between points.
I tried many logics and results were not the thing I wanted. problems I faced toward a smooth queued animation are:
I tried UIView.animate in the following:
a. I tried setting an animation duration let's say 2 sec, then after it finishes, it calls animation again within completion hander/closure/block, but it will result in a less than second stop between the two animations.
b. I tried to start 2 animations, the second is delayed with the exact duration go the first animation, but results also brief stop between 2 animations.
2.I tried animation with keyframes, but since I don't know all animations in advance, this won't work.
Can you help please with my approach toward a smooth dynamic animation?
Your own pseudocode answers your question. Just test whatever your condition, and if you need to animate again, work out the new start and end points and animate again:
func animate(start:Int, end:Int) {
UIView.animate(withDuration: 5, animations: {
// animate here based on new start and end
}, completion: { _ in
var weShouldDoItAgain = false
// figure out if we should do it again
// if so, change weShouldDoItAgain to true
if weShouldDoItAgain {
var start = start // and now change it to new value
var end = end // and now change it to new value
self.animate(start:start, end:end)
}
})
}
Just change all the values and types to suit your use case.

Animate view and stop midway

I want to make a view/header collaspe/expand animation, but I also want to be able to pause or stop from expanding/collapsing while the user takes his finger off the screen.
I have a current implementation for this, but the animation is not very smooth.
I will also add some images to explain better what I want to do.
So the first image is how it should look when expanded.
The second image is how it should look if the user decides to take take his finger off the screen while he would scroll slowly so the animation/the view should stop in a state similar to that.
The third image is how it should look when it is collapsed.
If someone has any recommendation how I could achieve this I would be very grateful.
If you are targeting iOS 10+, use UIViewPropertyAnimator which encapsulates an animation and allows scrubbing and controlling the animation:
Start, pause, resume, and stop animations; see the methods of the UIViewAnimating protocol.
Add animation blocks after the original animations start using the addAnimations(_:) and addAnimations(_:delayFactor:) methods.
Scrub through a paused animation by modifying the fractionComplete property.
Change the animation’s direction using the isReversed property.
Modify the timing and duration of a partially complete animation by pausing the animation and using the continueAnimation(withTimingParameters:durationFactor:) method to finish it.
You just need to wire up touches to UIViewPropertyAnimator object encapsulating the animation.
There are many good tutorials on how to start with it, e.g. this one.

Observe progress of UIView.animateWithDuration/CABasicAnimation?

Is there a way to observe the "time progress" of UIView.animateWithDuration...family of methods from UIView /alternatively CA animations?
I am animating a view's frame and I need to be informed how it is progressing.
My line of thinking was I can either
1) tap into CAAnimation related stuff or
2) observe the animated properties (like frame) and do my own calculations each screen frame.
Approach 1) turns out to be a dead end, inspecting the internal of how CAAnimations work told me absolutely nothing...and 2) is flawed as the "model layer tree is updated immediately and tapping into the presentation tree is difficult as the presentation layer is nil when you start.
I am pretty desperate, I was thinking that hooking into CADisplayLink will give me a tick and then I simply check something that is affected by the animation but there is nothing to tap to.
Do you think going the NSTimer way that is launched in the same scope as the animation method is ok? If I know animation duration then I can generate the progress myself.
If all you want is the time value, then you can do math on the CACurrentMediaTime() minus the animation start time. I have a sample project on Github called KeyframeViewAnimations that does exactly that.
That project supports pausing and resuming and scrubbing both UIView and CAAnimation based animations. In both cases it digs into the underlying CAAnimations.
I have another project that uses the values of the animated layer's presentationLayer in order to do hit testing so you can tap on an in-flight view and start/pause the animation. That one can be found here:
iOS-CAAnimation-group-demo
My code uses an NSTimer to update the progress of the animation. It would be better to use a CADisplayLink timer, as you mentioned.
I am also looking at the new UIViewPropertyAnimator class that was added to iOS 10. That makes pausing, reversing, and scrubbing UIView animations easy without having to dig into the underlying CAAnimations. See this thread I just posted:
Is there a way to observe changes to fractionComplete in UIViewPropertyAnimator

iOS - limit on UIView animate?

So I'm making a simple trivia game and I have a timerView that shrinks as time passes. When the user selects an answer, it needs to stop shrinking immediately - it must be very responsive. I give the user 10 seconds per question. Originally I would animate 10 times (with a duration of 1.0f), calling the next "segment" of animation in the completion block of the previous animation. In the completion block I would check to see if the user has tapped an answer, and if so I don't continue the chain. That solution works fine except that it's not very responsive because it's on a per second basis-- user taps an answer at the start of the second segment and the bar has a noticeable continuation.
My solution to THAT problem was to instead have 1000 animation calls with a duration of 0.01f. After doing that, the responsiveness was on point - the view stops animating as soon as I tap an answer -- the issue though, is that it's not actually 10 seconds, it takes more like 20.
So question number 1: what's the smallest time interval animateWithDuration can actually process properly?
Question number 2: is there a better way to accomplish what I'm trying to do accomplish?
ill answer question two: yes there definitely is a better way, have a look at CADisplayLink
use it to shrink your view a little bit each frame, and end the display link when you need to
the most responsive way is: the user taps an answer, you response in the touch callback, remove animations. you can remove animations by CALayer's removeAllAnimations method
Another way to do it is to set the view to shrinking using a single animation with linear timing, and then set the speed of the view's layer to 0 to pause the animation. When you set the speed on the layer to 0 the animation pauses instantly.
This works because under the covers, UIView animation actually creates and installs CAAnimation objects on the view's layers. It's possible to pause and continue an in-flight UIView animation just like you can a CAAnimation.
I have a project called KeyframeViewAnimations (link) on github that allows you to pause, continue, or "scrub" UIView and CAAnimations back and forth with a slider. You could use that technique. The tricky bit will be figuring out how far along the animation is.

NSTimer and Animation synced

I'm doing a countdown timer using NSTimer and a circle Animation like this one: GitHub.
My first question is: What CAMediaTimingFunction is for?
My second and most important question is: I'm getting NSTimer and my animation out of sync. Typically the timer reaches 0 before the animation. What is the best approach on this situation?
One way to be sure you are in sync is not using core animation, but setting the strokeEnd manually in the timer callbacks. I would suggest using a CADisplayLink instead of the NSTimer since it is bound to the refresh rate of the display.
Use its timestamp to calculate how much time passed and set the label text and the circle's strokeEnd appropiately.

Resources