3

First I created the CAShapeLayer for masking the UIView at the bottom with height of 10px like this:

CAShapeLayer *mask = [[CAShapeLayer alloc]init];
CGRect maskRect = CGRectMake(0, self.view.frame.size.height-10, self.view.frame.size.width, 10.0);
CGPathRef path = CGPathCreateWithRect(maskRect, NULL);
mask.path = path;
CGPathRelease(path);
mask.anchorPoint = CGPointMake(0.5, 1.0);
self.view.layer.mask = mask;

After commenting the above code I created a CALayer for masking the UIView at the bottom with height of 10px like this:

CALayer *mask = [CALayer layer];
mask.contents = (id)[[self getImg]CGImage];
mask.frame = CGRectMake(0, self.view.frame.size.height-5, self.view.frame.size.width, 10.0);
mask.anchorPoint = CGPointMake(0.5, 1.0);
self.view.layer.mask = mask;

Question 1:

To perfectly touch the bottom not a pixel above or below, for CAShapeLayer the CGRect I defined is

CGRectMake(0, self.view.frame.size.height-10, self.view.frame.size.width, 10.0);

and for CALayer the CGRect I defined is

CGRectMake(0, self.view.frame.size.height-5, self.view.frame.size.width, 10.0);

why -10 for CAShapeLayer and why -5 for CALayer ?


The animation code and its effects on CAShapeLayer and CALayer:

CGRect oldBounds = mask.bounds;
    CGRect newBounds = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height/2);

    [UIView animateWithDuration:1.0 animations:^{
        CABasicAnimation* revealAnimation = [CABasicAnimation animationWithKeyPath:@"bounds"];
        revealAnimation.fromValue = [NSValue valueWithCGRect:oldBounds];
        revealAnimation.toValue = [NSValue valueWithCGRect:newBounds];
        revealAnimation.duration = 0.5;
        [mask addAnimation:revealAnimation forKey:@"revealAnimation"];
    }];
    // Update the bounds so the layer doesn't snap back when the animation completes.
    mask.bounds = newBounds;

Effect on CAShapeLayer the position is changed but no effect on hight like this:

enter image description here

Effect on CALayer which worked perfectly and the result I wanted:

enter image description here

Question 2: Why CAShapeLayer changed the position not the height?

I don't know why but I am having a feeling like CALayer animation is not going smooth?

Question 3:

The [UIView animateWithDuration:1.0 animations:^{ ... block do not have any effect on animation, why?

S.J
  • 3,063
  • 3
  • 33
  • 66

1 Answers1

0

Answer 1: Not sure why it is 5 and 10 for CAShapeLayer and CALayer, need to debug closely, but maybe problem is in adjusting anchorPoint or because you use path of shape layer

Answer 2: About effect on CAShapeLayer: this is because you assigned CGPath to it, and changed shape layer frame, but not path. So you need to set new path property with correct coordinates. Something like this:

CGRect maskRect =  CGRect newBounds = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height/2);
CGPathRef path = CGPathCreateWithRect(maskRect, NULL);
mask.path = path;
CGPathRelease(path);

Answer 3:

CABasicAnimation is class, which will do all animation, and you don't need to use it in UIView animateWithDuration block.

This code should work as expected:

CABasicAnimation* revealAnimation = [CABasicAnimation animationWithKeyPath:@"bounds"];
revealAnimation.fromValue = [NSValue valueWithCGRect:oldBounds];
revealAnimation.toValue = [NSValue valueWithCGRect:newBounds];
revealAnimation.duration = 0.5;
[mask addAnimation:revealAnimation forKey:@"revealAnimation"];
Vitalii Gozhenko
  • 9,220
  • 2
  • 48
  • 66