The Secret Life of a CALayer (Part 3): CABasicAnimation (Xcode)


CABasicAnimation is one of five types of animation available to a CALayer, the others being CATransition, CAAnimationGroup, CAPropertyAnimation,  and CAKeyframeAnimation. And we are going to use it in this post to animate the hitTest from the previous post.

To do this we need first to extend the interface of our .m view controller from last time to look like this:


@interface HitTestViewController ()
{
    CALayer *blueLayer;
    CALayer *redLayer;
    CALayer *yellowLayer;
    CALayer *greenLayer;
    CGRect positionOne;
    CGRect positionTwo;
    CGRect positionThree;
    CGRect positionFour;

    CALayer *hitLayer;
}
@end


Next we're going to alter the -viewDidAppear: method:


-(void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
    blueLayer = [[CALayer alloc] init];
    positionOne = CGRectMake(100, 100, 100, 100);
    blueLayer.frame = positionOne;
    blueLayer.backgroundColor = [UIColor blueColor].CGColor;
    blueLayer.name = @"One";
    blueLayer.contents = (id) [UIImage imageNamed:@"plane"].CGImage;
    
    [self.view.layer addSublayer:blueLayer];
    
    redLayer = [[CALayer alloc] init];
    positionTwo= CGRectMake(100, 400, 100, 100);
    redLayer.frame = positionTwo;
    redLayer.backgroundColor = [UIColor redColor].CGColor;
    redLayer.name=@"Two";
    
    [self.view.layer addSublayer:redLayer];
    
    yellowLayer = [[CALayer alloc] init];
    positionThree = CGRectMake(400, 100, 100, 100);
    yellowLayer.frame = positionThree;
    yellowLayer.backgroundColor = [UIColor yellowColor].CGColor;
    yellowLayer.name = @"Three";
    
    [self.view.layer addSublayer:yellowLayer];
    
    greenLayer = [[CALayer alloc] init];
    positionFourCGRectMake(400, 400, 100, 100);
    greenLayer.frame =positionFour;
    greenLayer.backgroundColor = [UIColor greenColor].CGColor;
    greenLayer.name=@"Four";
    
    [self.view.layer addSublayer:greenLayer];
    
    
}


Before adding an additional method called makeLayerBig:


- (void)makeLayerBig:(CALayer *)layerName{

    // A pointer to the old frame size for our animation fromValue
    CGRect oldFrame = layerName.frame;
    // A pointer to the new frame size for our animation toValue
    CGRect newFrame = oldFrame;
    // Adjust new frame size and origin    
    newFrame.size = CGSizeMake(768, 1024);
    newFrame.origin = CGPointMake(0, 0);
    // Place the animating layer over the top of the others
    hitLayer.zPosition=1;

    // Prepare the animation from the old size to the new size
    CABasicAnimation *theAnimation = [CABasicAnimation animationWithKeyPath:@"frame"];
    theAnimation.duration=1;
    // Make this view controller the delegate so it knows when the animation starts and ends
    theAnimation.delegate=self;
    // Use fromValue and toValue
    theAnimation.fromValue = [NSValue valueWithCGRect:oldFrame];
    theAnimation.toValue = [NSValue valueWithCGRect:newFrame];
   
    
   
    // Update the frame of the layer
    layerName.frame = newFrame;
    
    // Add the animation to the layer
    [layerName addAnimation:theAnimation forKey:@"frame"];
    
}


Here you see that we create a basic animation using an NSValue that we are going from and to. It is then a case of adding that animation to the layer with the addAnimation: method. Now all there is to be done is to add the trigger to our touches, like so:


- (void)touchesEnded:(NSSet*)touches withEvent:(UIEvent*)event {

     if ([self.view subviews].count==0)
    {
        CGPoint location = [[touches anyObject] locationInView:self.view];
        hitLayer = [self.view.layer hitTest:[self.view convertPoint:location fromView:nil]];

// The extra code makes sure we don't transform the view controller's main view
   
if(hitLayer!=self.view.layer)
{
  
  
        [self makeLayerBig:hitLayer];
        [self displayInfo:hitLayer];}
}


And that's it. Try it out for yourself.


The Secret Life of a CALayer: Part 1 | Part 2 | Part 3 Part 4


Comments