Search code examples
objective-ccocoa-touchcocoacore-animationobjective-c-blocks

Using CAMediaTimingFunction with block-based UIView animations


The View Programming Guide for iOS tells us that block-based animations are the way forward, as opposed to the now almost deprecated begin/commit style animations:

Note: If you are writing an application for iOS 4 or later, you should use the block-based methods for animating your content instead. For information on how to use those methods, see “Starting Animations Using the Block-Based Methods.”

But now I'm in a situation where I need to use custom timing functions CAMediaTimingFunction so I've resorted to using CATransactions and CABasicAnimations. These classes uses the same semantical language as the deprecated UIView animations style with methods like [CATransaction begin] and [CATransaction commit]. It just feels odd in the middle of apps where everything else is block-based.

Is there a way to combine concepts like the CAMediaTimingFunctions with block-based animations?

Update 1:

A piece of example code that I would like to 'blockify' looks like this:*

[CATransaction begin];
{    
    [CATransaction setValue:[NSNumber numberWithFloat:3.0f] forKey:kCATransactionAnimationDuration];

    CGPoint low = CGPointMake(0.150, 0.000);
    CGPoint high = CGPointMake(0.500, 0.000);

    [CATransaction begin];
    {
        CAMediaTimingFunction* perfectIn = [CAMediaTimingFunction functionWithControlPoints:low.x :low.y :1.0 - high.x :1.0 - high.y];
        [CATransaction setAnimationTimingFunction: perfectIn];
        CABasicAnimation *fadeIn = [CABasicAnimation animationWithKeyPath:@"opacity"];
        fadeIn.fromValue = [NSNumber numberWithFloat:0];
        fadeIn.toValue = [NSNumber numberWithFloat:1.0];
        [viewB.layer addAnimation:fadeIn forKey:@"animateOpacity"];
    }
    [CATransaction commit];
}
[CATransaction commit];

Update 2

I've made an example project for another question of mine that contains the code above. It's on github.


Solution

  • But now I'm in a situation where I need to use custom timing functions CAMediaTimingFunction so I've resorted to using CATransactions and CABasicAnimations. These classes uses the same semantical language as the deprecated UIView animations style with methods like [CATransaction begin] and [CATransaction commit]. It just feels odd in the middle of apps where everything else is block-based.

    I think you are misreading the documentation.

    Block based animations are the way to do UIView animations. Period. Full stop.

    This statement DOES NOT correspond to CoreAnimation. You still have to use begin/commit for CoreAnimation. Don't make the assumption that CA begin and commit are bad, just because a higher level construct (UIView) deprecated begin/commit.

    Is there a way to combine concepts like the CAMediaTimingFunctions with block-based animations?

    • If you need the advanced capabilities of Core Anmiation, such as custom timings, you should use CoreAnimation the way it is intended (with begin/commit, etc.)
    • If you are trying to animate CALayers, use Core Animation.
    • If you are doing high-level UIView based animations, use the UIView block-based animations.