首页 文章

使用CAGradientLayer作为后备存储在UIView上绘制线条

提问于
浏览
0

我创建了一个 UIView 子类,它的层使用 CAGradientLayer . 这工作正常 . 现在我想在渐变的末尾画一条线(用作分隔符) . 我以为我可以使用 drawRect 方法:

public class GradientView : UIView
{
    // accessors
    private CAGradientLayer gradientLayer {
        // read-only
        get { return (CAGradientLayer)this.Layer; }
    }

    public CGColor[] Colors {
        // set the colors of the gradient layer
        get { return this.gradientLayer.Colors; }
        set { this.gradientLayer.Colors = value; }
    }

    [Export ("layerClass")]
    public static Class LayerClass ()
    {
        // use a different Core Animation layer for its backing store
        // normally a CALayer is used for a UIView
        return new Class (typeof(CAGradientLayer));
    }

    public override void Draw (RectangleF rect)
    {

        PointF pointA = new PointF (0, rect.Height);
        PointF pointB = new PointF (rect.Width, rect.Height);
        CAShapeLayer line = new CAShapeLayer ();
        UIBezierPath linePath = new UIBezierPath ();
        linePath.MoveTo (pointA);
        linePath.AddLineTo(pointB);
        line.Path = linePath.CGPath;
        line.FillColor = null;
        line.Opacity = 1.0f;
        line.StrokeColor = UIColor.Black.CGColor;

        this.gradientLayer.AddSublayer (line);

        base.Draw (rect);
    }
}

但我得到了黑色背景 . 我可以使用 drawRect 吗?或者我如何在其上添加一行?

我使用C#作为语言,但您也可以在Objective-C中提供解决方案 . 自动布局确定 GradientView 的大小,我的旧解决方案也适用于方向更改 .

Edit:

我试过Cyrille说的话:

public class GradientView : UIView
{
    // accessors
    private CAShapeLayer line;

    private CAGradientLayer gradientLayer {
        // read-only
        get { return (CAGradientLayer)this.Layer; }
    }

    public CGColor[] Colors {
        // set the colors of the gradient layer
        get { return this.gradientLayer.Colors; }
        set { this.gradientLayer.Colors = value; }
    }

    public GradientView()
    {
        PointF pointA = new PointF (0, this.Bounds.Height);
        PointF pointB = new PointF (this.Bounds.Width, this.Bounds.Height);
        line = new CAShapeLayer ();
        UIBezierPath linePath = new UIBezierPath ();
        linePath.MoveTo (pointA);
        linePath.AddLineTo(pointB);
        line.Path = linePath.CGPath;
        line.FillColor = null;
        line.Opacity = 1.0f;
        line.StrokeColor = UIColor.Black.CGColor;
        line.LineWidth = 1.0f;

        this.gradientLayer.AddSublayer (line);
    }

    [Export ("layerClass")]
    public static Class LayerClass ()
    {
        // use a different Core Animation layer for its backing store
        // normally a CALayer is used for a UIView
        return new Class (typeof(CAGradientLayer));
    }

    public override void LayoutSubviews ()
    {
        PointF pointA = new PointF (0, this.Bounds.Height-2);
        PointF pointB = new PointF (this.Bounds.Width, this.Bounds.Height-2);
        UIBezierPath linePath = new UIBezierPath ();
        linePath.MoveTo (pointA);
        linePath.AddLineTo(pointB);

        line.Path = linePath.CGPath;

        base.LayoutSubviews ();
    }
}

这似乎做我想要的,除了线不是细线 . CAShapeLayer 不适合这个吗?

Solution:

当然可以使用 CAShapeLayer ,但是如果我必须在 drawRect 中设置东西,那么我就完全在那里画线 . 现在我的解决方案看起来如下所示:

public class GradientView : UIView
{
    // accessors
    private CAShapeLayer line;

    private CAGradientLayer gradientLayer {
        // read-only
        get { return (CAGradientLayer)this.Layer; }
    }

    public CGColor[] Colors {
        // set the colors of the gradient layer
        get { return this.gradientLayer.Colors; }
        set { this.gradientLayer.Colors = value; }
    }

    public GradientView()
    {
        this.BackgroundColor = UIColor.Clear;
    }

    [Export ("layerClass")]
    public static Class LayerClass ()
    {
        // use a different Core Animation layer for its backing store
        // normally a CALayer is used for a UIView
        return new Class (typeof(CAGradientLayer));
    }

    public override void Draw (RectangleF rect)
    {
        base.Draw (rect);

        // get graphics context
        CGContext context = UIGraphics.GetCurrentContext ();

        // start point
        context.MoveTo (0, rect.Height);

        // end point
        context.AddLineToPoint (rect.Width, rect.Height);

        context.SetLineWidth (1.0f);

        context.SetShouldAntialias(false);

        // draw the path
        context.DrawPath (CGPathDrawingMode.Stroke);
    }

1 回答

  • 1

    使用 CAGradientLayer 作为视图的后备层不会阻止您在初始化时在视图中添加另一个 CAShapeLayer . 然后,您可以使用此形状图层来绘制直线,方法是相应地设置其 path 属性(并在 -layoutSubviews 中的任何时候重新计算边界,以便对方向/布局更改做出正确反应) .

相关问题