图层蒙版的面具。核心动画

问题描述 投票:0回答:2

我深入到核心动画中并且遇到了一些层屏蔽问题

出于学习原因,我尝试使用透明的东西制作复杂的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什么都不做!这不像面具必须做的那样工作。 我该怎么办?

ios xamarin.ios core-animation
2个回答
0
投票

但我也希望能在圆圈中制作透明而不是黑色。

解决方案探索版:

您还可以使用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);

其他代码没有改变。

enter image description here

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

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

我测试过CAShapeLayer不能使用此功能来改变图像的颜色。 CAShapeLayer Class

然而,我发现qazxsw poi可以做到这一点。它有一个qazxsw poi属性。这个属性来自UiView .UIImageView

TintColor

UIView.TintColor Property

改成:

enter image description here

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

enter image description here

如果你使用Layer.Mask = maskOfMaskLayer; 只是在图层上覆盖你的图像,而enter image description here是相反的效果,它只显示覆盖该部分的背景,其余的区域将是white.AddSublayer


0
投票

所有需要做的就是通过Core Graphics的反转图像颜色,任何颜色到透明,任何颜色都是透明的。在这种情况下,黑色就足够了

Layer.Mask

并将掩模图层的蒙版设置为父图层

CALayer.Mask

最终版本的代码:

public static UIImage GetRevertImage(UIImage image, CGRect rect, CGRect cropFrame)
{
    UIGraphics.BeginImageContextWithOptions(rect.Size, false, 1);
    UIColor.Black.SetColor();
    UIGraphics.RectFill(rect);
    image.Draw(cropFrame, CGBlendMode.DestinationOut, 1);

    var newImage = UIGraphics.GetImageFromCurrentImageContext();
    UIGraphics.EndImageContext();
    return newImage;
}

© www.soinside.com 2019 - 2024. All rights reserved.