Animate the mask of a mask of a CALayer

时光怂恿深爱的人放手 提交于 2019-12-13 12:36:24

问题


Goal:
I am drawing a custom shape that has a gradient. I also want to animate the drawing of this shape by having it draw in from left to right.

Problem:
The code below works on an iPad simulator, but it doesn't work on my iPad 4 running iOS 7. Does anyone know how to make this work on the device? Is there a different way to achieve this same result?

Explanation of my Code:
My code works (only on simulator) using 3 CALayers.

  • gradientLayer holds my gradient.
  • shapeMaskLayer holds my custom shape.
  • animationMaskLayer animates it's path to simulate drawing from left to right

animationMaskLayer --masks--> shapeMaskLayer --masks--> gradientLayer

I then animate the frame of animationMaskLayer to animate the whole shape.

Code:

// Animation Mask Rects
CGPathRef leftStartingRectPath = CGPathCreateWithRect(CGRectMake(0, 0, 0, self.frame.size.height), 0);
CGPathRef fullViewRectPath = CGPathCreateWithRect(CGRectMake(0, 0, self.frame.size.width, self.frame.size.height), 0);

// Animation Mask Layer
CAShapeLayer *animationMaskLayer = [CAShapeLayer layer];
animationMaskLayer.path = fullViewRectPath;
animationMaskLayer.fillColor = UIColor.blackColor.CGColor;

// Shape Mask Layer
CAShapeLayer *shapeMaskLayer = [CAShapeLayer layer];
shapeMaskLayer.path = CGPathCreateWithEllipseInRect(self.bounds, 0);
shapeMaskLayer.fillColor = [UIColor blueColor].CGColor;
shapeMaskLayer.mask = animationMaskLayer;

// Gradient Layer
CAGradientLayer *gradientLayer = [CAGradientLayer layer];
gradientLayer.frame = self.bounds;
gradientLayer.colors = self.colors;
gradientLayer.mask = shapeMaskLayer;
mountainLayer.anchorPoint = pt(0, 0);
mountainLayer.position = pt(0, 0);
[self.layer addSublayer:gradientLayer];

// Left To Right Animation
CABasicAnimation *leftToRightAnimation = [CABasicAnimation animationWithKeyPath:@"path"];
leftToRightAnimation.duration = 0.5;
leftToRightAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
leftToRightAnimation.fromValue = (__bridge id)leftStartingRectPath;
leftToRightAnimation.toValue = (__bridge id)fullViewRectPath;
leftToRightAnimation.fillMode = kCAFillModeForwards;
leftToRightAnimation.removedOnCompletion = NO;
[animationMaskLayer addAnimation:leftToRightAnimation forKey:@"animatePath"];

// Memory Management
CGPathRelease(leftStartingRectPath);
CGPathRelease(fullViewRectPath);

回答1:


Animating the mask of a mask? I'm surprised that even works in the simulator.

Have you tried nesting two layers, with the parent layer with masksToBounds on? You can then set an independent mask on both layers, and the outer layer will effectively mask your inner layer with its own mask (due to masksToBounds). It probably doesn't matter which layer gets which mask (because you want the intersection of both masks).

With the code you listed in your question, you would just need to add one line, and comment out one line to get the correct functionality:

self.layer.mask = animationMaskLayer;
//    shapeMaskLayer.mask = animationMaskLayer;


来源:https://stackoverflow.com/questions/20132875/animate-the-mask-of-a-mask-of-a-calayer

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!