首页 > 解决方案 > 图层蒙版的蒙版。核心动画

问题描述

我深入了解核心动画并且在图层蒙版方面遇到了一些问题

出于学习原因,我尝试用透明的东西制作一个复杂的 UI 层

这个观点一个有并投入了ViewController

public class TestView : UIView
    {
        public TestView()
        {
            Layer.Delegate = this;
            Frame = new CGRect(100f,200f, 100f, 100f);
        }

        public override void LayoutSublayersOfLayer(CALayer layer)
        {
            base.LayoutSublayersOfLayer(layer);

            var bounds = Bounds;
            var circleFrame = new CGRect(20, 20, 60, 60);
            var imageFrame = new CGRect(30, 30, 40, 40);

            Layer.BorderWidth = 5;
            Layer.BorderColor = UIColor.Red.CGColor;
            Layer.CornerRadius = 4;

            var gradientLayer = new CAGradientLayer();
            gradientLayer.Colors = new[] { UIColor.Green.CGColor, UIColor.Red.CGColor };
            gradientLayer.Frame = bounds;
            Layer.AddSublayer(gradientLayer);

            var maskOfGradientLayer = new CAShapeLayer();
            var path = UIBezierPath.FromRoundedRect(circleFrame, 30);
            path.UsesEvenOddFillRule = true;
            maskOfGradientLayer.Path = path.CGPath;
            maskOfGradientLayer.FillRule = CAShapeLayer.FillRuleEvenOdd;
            maskOfGradientLayer.FillColor = UIColor.Black.CGColor;
            maskOfGradientLayer.Frame = bounds;
            gradientLayer.Mask = maskOfGradientLayer;

            var maskOfMaskLayer = new CAShapeLayer();
            maskOfMaskLayer.Frame = imageFrame;
            maskOfMaskLayer.FillColor = UIColor.Black.CGColor;
            maskOfMaskLayer.Contents = Bundles.ImageOff.CGImage;

            Layer.AddSublayer(maskOfMaskLayer);
        }
    }

我有,这正是我想要的。

在此处输入图像描述

但我也希望可以使圆形透明而不是黑色。

我试着做这样maskOfGradientLayer.Mask = maskOfMaskLayer. 但是这种方式maskOfMaskLayer什么都不做!它不像面具必须做的那样工作。
我应该怎么做?

标签: iosxamarin.ioscore-animation

解决方案


但我也希望可以使圆形透明而不是黑色。

解决方案探索版:

您还可以使用UIBezierPath来绘制您想要的内容,并设置为maskOfMaskLayer

var maskOfMaskLayer = new CAShapeLayer();
maskOfMaskLayer.Frame = imageFrame;
maskOfMaskLayer.FillColor = UIColor.Black.CGColor;
maskOfMaskLayer.Contents = Bundles.ImageOff.CGImage;

Layer.AddSublayer(maskOfMaskLayer);

替换为以下代码:

UIBezierPath offCirclePath = new UIBezierPath();

// draw an arc
offCirclePath.AddArc(new CGPoint(50, 50), circleFrame.Width / 3, (nfloat)(1.75 * Math.PI), (nfloat)(1.25 * Math.PI), true);

//draw a line
offCirclePath.MoveTo(new CGPoint(50, 30));
offCirclePath.AddLineTo(new CGPoint(50, 45));

//set to maskOfMaskLayer 
var maskOfMaskLayer = new CAShapeLayer();
maskOfMaskLayer.FillColor = UIColor.Clear.CGColor;
maskOfMaskLayer.Path = offCirclePath.CGPath;
maskOfMaskLayer.LineWidth = 5;
maskOfMaskLayer.StrokeColor = UIColor.White.CGColor;
maskOfMaskLayer.LineCap = new NSString("round");

Layer.AddSublayer(maskOfMaskLayer);

其他代码未更改。

在此处输入图像描述

但我从一开始就考虑设置任何自定义图像。

解决方案二:(方向错误)

我已经测试过CAShapeLayer不能有这个功能来改变图像的颜色。CAShapeLayer 类

但是,我发现UIImageView可以这样做。它有一个属性。这个TintColor属性来自 UiView。UIView.TintColor 属性

在此处输入图像描述

var maskOfMaskLayer = new CAShapeLayer();
maskOfMaskLayer.Frame = imageFrame;
maskOfMaskLayer.FillColor = UIColor.Black.CGColor;
maskOfMaskLayer.Contents = Bundles.ImageOff.CGImage;

Layer.AddSublayer(maskOfMaskLayer);

改成:

UIImageView imageView = new UIImageView();
imageView.Frame = imageFrame;
imageView.Image = Bundles.ImageOff;
imageView.TintColor = UIColor.White;

AddSubview(imageView);

在此处输入图像描述

正确的解决方案

很抱歉误解了真正的想要的效果,我更新如下:

Layer.Mask = maskOfMaskLayer;

在此处输入图像描述

如果你使用AddSublayer只是在图层上覆盖你的图像,并且Layer.Mask是相反的效果,它只显示覆盖部分的背景,其余区域将是白色的。CALayer.Mask


推荐阅读