【问题标题】:Draw method doesn't get called from the custom UIView不会从自定义 UIView 调用 Draw 方法
【发布时间】:2019-12-23 10:25:41
【问题描述】:

我正在为 iOS 创建一个自定义地图图钉(注解),绘制其路径,然后将 UIView 转换为图像,使用此 method

public static UIImage AsImage(this UIView view)
{
    try
    {
        UIGraphics.BeginImageContextWithOptions(view.Bounds.Size, true, 0);
        var ctx = UIGraphics.GetCurrentContext();
        view.Layer.RenderInContext(ctx);
        var img = UIGraphics.GetImageFromCurrentImageContext();
        UIGraphics.EndImageContext();
        return img;
    }
    catch (Exception)
    {
        return null;
    }
}

这是UIView派生类,我在其中绘制注释路径:

public class PinView : UIView
{
    public PinView()
    {
        ContentMode = UIViewContentMode.Redraw;
        SetNeedsDisplay();
    }
    private readonly CGPoint[] markerPathPoints = new[]
   {
        new CGPoint(25f, 5f),
        new CGPoint(125f, 5f),
        //other points    };

    public override void Draw(CGRect rect)
    {
        base.Draw(rect);
        //get graphics context
        CGContext context = UIGraphics.GetCurrentContext();
        //set up drawing attributes
        context.SetLineWidth(10);
        UIColor.White.SetFill();
        UIColor.Black.SetStroke();

        //create geometry
        var path = new CGPath();
        path.MoveToPoint(markerPathPoints[0].X, markerPathPoints[0].Y);
        for (var i = 1; i < markerPathPoints.Length; i++)
        {
            path.AddLineToPoint(markerPathPoints[i].X, markerPathPoints[i].Y);
        }

        path.CloseSubpath();
        //add geometry to graphics context and draw it
        context.AddPath(path);
        context.DrawPath(CGPathDrawingMode.FillStroke);
    }

我正在修改 Xamarin.Forms sample of the MapCustomRenderer,而不是从文件中加载注释,而是从视图中加载它:

annotationView.Image = new PinView().AsImage();

PinView.Draw() 永远不会被调用!

【问题讨论】:

    标签: ios xamarin uiview


    【解决方案1】:

    方法Draw在控件第一次加载时会在ViewDidLoad之后被调用,由系统自动调用。

    在您的情况下,您没有设置 PinView 的 Rect(Frame) 。所以Draw方法永远不会被调用,因为Rect默认为零。

    所以你可以在构造函数中设置一个默认框架

    public PinView()
    {
      Frame = new CGRect (0,0,xx,xxx);
      ContentMode = UIViewContentMode.Redraw;
      SetNeedsDisplay();
    }
    

    【讨论】:

    • 知道为什么视图显示为黑盒子吗?没有定义黑色,并且视图在传递给自定义控件渲染器的SetNativeControl 时工作正常
    • 您可以提供一个包含问题的示例,以便我可以在我身边进行测试。
    • 我想是因为UIColor.Black.SetStroke();
    • 在附件中应该是UIColor.Blue.SetStroke();
    【解决方案2】:

    视图需要添加到视图层次结构中,在我的例子中,添加到MKAnnotationView, 所以在CustomMKAnnotationView 构造函数中:

    public CustomMKAnnotationView(IMKAnnotation annotation, string id)
        : base(annotation, id)
    {
        var pin = new PinView(new CGRect(0, 0, 110, 110));
        pin.BackgroundColor = UIColor.White.ColorWithAlpha(0);
        Add(pin);
    }
    

    UIView 的构造函数中,Frame 应该被初始化为 Lucas Zhang 所说的:

    public PinView(CGRect rectangle)
    {
        Frame = rectangle;
        ContentMode = UIViewContentMode.Redraw;
        SetNeedsDisplay();
    }
    

    通过这些更改,将调用 Draw 方法。

    【讨论】:

    • 不要忘记接受答案,这将帮助更多的人:)
    • 您可以编辑您的答案并提供更多详细信息或编辑我的答案,也许这两个答案是相似的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-14
    • 1970-01-01
    • 2020-01-24
    • 2018-03-02
    • 1970-01-01
    • 2012-07-31
    相关资源
    最近更新 更多