Question

I have the code below to animate a score label. How would you go about changing it so it becomes an ease out animation?

Thanks

- (void)animateFrom:(float)fromValue toValue:(float)toValue
{
    self.scoreAnimationFrom = fromValue;
    self.scoreAnimationTo = self.question.correctValue;

    CADisplayLink *link = [CADisplayLink displayLinkWithTarget:self selector:@selector(animateNumber:)];

    self.startTimeInterval = CACurrentMediaTime();
    [link addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
}

- (void)animateNumber:(CADisplayLink *)link
{
    float dt = ([link timestamp] - self.startTimeInterval) / self.duration;

    if (dt >= 1.0)
    {
        [link removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
        return;
    }

    float current = ((self.scoreAnimationTo - self.scoreAnimationFrom) * dt + self.scoreAnimationFrom);
    self.valueLabel.text = [NSString stringWithFormat:@"%f", current];
}
Was it helpful?

Solution

The progress of your animation is described by the dt variable, which is a value between 0 and 1. Applying an ease out timing to your animation is as simple as funnelling this value into an appropriate timing function before applying it further. The responsibility of a timing function is to turn the original value into another value between 0 and 1, following a specific timing curve. For more information about timing functions, simply refer to Apple documentation.

In your case, you therefore need to apply an ease out timing function to dt, something like:

dt = [[TimingFunction easeOutTimingFunction] solveForInput:dt];

Core Animation provides the CAMediaTimingFunction class, but sadly its _solveForInput: solving method is private. There exists several open-source implementations of timing functions that you can use instead, e.g. https://github.com/warrenm/AHEasing.

If you are curious, I also recently implemented a method equivalent to _solveForInput: within a category of CAMediaTimingFunction.

OTHER TIPS

I have made a very simple solution by using a sin function instead of the complex curve calculation with polynomial coefficients:

//EasyOut
dt = sin(dt*M_PI/2)+0.01f;

Enjoy it :)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top