Search code examples
ioscore-animationcalayer

how can I animate a CAlayer's bounds to progressively reveal an image?


For certain reasons, I'm trying to avoid using a CAScrollLayer to do this. The effect I'm going after is to progressively reveal (from bottom to top) a CALayer's content (a png I previously loaded in). So I thought about doing this:

    layer.anchorPoint = CGPointMake(.5, 1);
    CABasicAnimation* a = [CABasicAnimation animationWithKeyPath:@"bounds.size.height"];
    a.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
    a.fillMode = kCAFillModeBoth;
    a.removedOnCompletion = NO;
    a.duration = 1;
    a.fromValue = [NSNumber numberWithFloat:0.];
    a.toValue = [NSNumber numberWithFloat:layer.bounds.size.height];
    [layer addAnimation:a forKey:nil];

The problem with this is you can tell the layer's content is scaled with the bounds. I was trying for the bounds to change but the content to stay always the original size, so that effectively the bounds clip the image and as I increase bounds.height, the image "Reveals" itself.

Any ideas as to how to pull it off or what might I be missing?


Solution

  • Ok I got it to work, but I basically had to update the layer's frame too, to reflect the change in anchor point:

      [CATransaction setValue:(id)kCFBooleanTrue forKey:kCATransactionDisableActions];
      layer.contentsGravity = kCAGravityTop;
      layer.masksToBounds = YES;
      layer.anchorPoint = CGPointMake(.5, 1);
      CGRect newFrame = layer.frame;
      newFrame.origin.y += newFrame.size.height / 2;
      layer.frame = newFrame;
      [CATransaction setValue:(id)kCFBooleanFalse forKey:kCATransactionDisableActions];
    
      a.toValue = [NSNumber numberWithFloat:layer.bounds.size.height];
      [layer addAnimation:a forKey:nil];