CAAnimationGroup doesn't do all animations

  • Boy, this CoreAnimation doesn't come easy to me...

    I'm struggling with CAAnimationGroup in conjunction with -
    actionForKey:, kCAOnOrderIn...

    I like the ability to override implicit animations by providing custom
    -actionForLayer:forKey:. This way I can simply add my sublayer to the
    rootlayer, and my animation/transition will automatically kick in. In
    this case I'd like them fade in while popping. But when I attempt
    this, only the fade-in seems to be executed. The code in my CALayer
    subclass looks something like this:

    + (id)layerWithInfo:(MyInfoClass *)info
    MyLayerClass *layer = (MyLayerClass *)[super layer]; = info;

    // Configure layer, based on info data; turn off animation while
    // [snip
    [CATransaction setValue:(id)kCFBooleanTrue
    layer.anchorPoint = CGPointMake (0, 0); // Use lower/left corner as
    with views
    layer.frame      = CGRectMake (0, 0, 40, 40);
    layer.contents  = aCGImageRef;
    layer.delegate  = layer; // So we can provide custom impicit
    [CATransaction setValue:(id)kCFBooleanFalse

    return layer;

    - (id<CAAction>)actionForKey:(NSString *)key
    // Return default animations for various events and properties
    if ([key isEqualToString:kCAOnOrderIn])
      // Create and configure a basic animation for the fade in
      // Use key path since we'll be in a group.
      CABasicAnimation *alphaAnim = [CABasicAnimation
      alphaAnim.fromValue = [NSNumber numberWithFloat:0.0];
      alphaAnim.toValue  = [NSNumber numberWithFloat:1.0];

      // Create keyframe animation for the pop effect
      CAKeyframeAnimation *sizeAnim = [CAKeyframeAnimation

      // Calculate rectangle sizes and frames for the various states
      NSRect endRect  = NSMakeRect (0, 0, 40, 40);
      NSRect startRect = NSMakeRect (NSMidX (endRect), NSMidY (endRect),
    0, 0); // zero-rect
      NSRect popRect  = NSInsetRect (endRect, -10, -10);

      // Create array of values for animation
      NSArray *values = [NSArray arrayWithObjects:
      [NSValue valueWithRect:startRect],
      [NSValue valueWithRect:popRect],
      [NSValue valueWithRect:endRect],
      sizeAnim.values = values;

      // Create array of key times for animation
      NSArray *times = [NSArray arrayWithObjects:
      [NSNumber numberWithFloat:0.0],
      [NSNumber numberWithFloat:0.8],
      [NSNumber numberWithFloat:1.0],
      sizeAnim.keyTimes = times;

      // Put the two animations together into one animation group
      CAAnimationGroup *group = [CAAnimationGroup animation];
      group.animations = [NSArray arrayWithObjects:alphaAnim, sizeAnim,
      group.duration = 3.0;

      return group;
    else if ([key isEqualToString:@"position"])
      // Move layer to new position
      CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:key];
      anim.timingFunction = [CAMediaTimingFunction
      anim.duration = self.moveDuration; // Calculated in the calling code
      return anim;
      return nil;

    In my view code I then just call:
    layer = [MyLayerClass layer];
    [self.layer addSublayer:layer];

    So why does my layer only animate on the opacity and not on the frame?

    The "position" part works well in actionForKey: when implicitly
    setting the position of the layer.


    P.S. I'm afraid this is not my last CA related question on this list.
    I hope you'll have more patience with me...
  • On 20-Jan-08, at 5:49 PM, Joachim wrote:

    > So why does my layer only animate on the opacity and not on the frame?

    Animating the scale (key = @"transform.scale") rather than the frame
    makes it work. Although I haven't looked further into it, I reckon
    that even though the frame changes its size, the graphics herein
    doesn't. Therefore I didn't see the animation.

previous month january 2008 next month
  1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31      
Go to today