简体   繁体   English

对CALayer的蒙版进行动画处理

[英]Animate the mask of a mask of a CALayer

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? 以下代码可在iPad模拟器上运行,但不能在运行iOS 7的iPad 4上运行。有人知道如何使此代码在设备上运行吗? Is there a different way to achieve this same result? 有没有其他方法可以达到相同的结果?

Explanation of my Code: 我的代码说明:
My code works (only on simulator) using 3 CALayers. 我的代码使用3个CALayers(仅在模拟器上)有效。

  • gradientLayer holds my gradient. gradientLayer保留我的渐变。
  • shapeMaskLayer holds my custom shape. shapeMaskLayer保留我的自定义形状。
  • animationMaskLayer animates it's path to simulate drawing from left to right animationMaskLayer对其路径进行动画处理以模拟从左到右的绘图

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

I then animate the frame of animationMaskLayer to animate the whole shape. 然后,我对animationMaskLayer的帧进行animationMaskLayer以对整个形状进行动画处理。

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);

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? 您是否尝试过嵌套两层,并在其父层上masksToBounds 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 ). 然后,您可以在两层上都设置一个独立的蒙版,并且外层将使用其自己的蒙版有效地对您的内层进行蒙版(由于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;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM