วิธีการวาดไม่ได้รับการเรียกจาก UIView ที่กำหนดเอง

ฉันกำลังสร้างหมุดแผนที่แบบกำหนดเอง (คำอธิบายประกอบ) สำหรับ iOS วาดเส้นทางของมันแล้วแปลง UIView เป็นรูปภาพ โดยใช้ วิธีการ:

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 ตัวอย่าง MapCustomRenderer แทนที่จะโหลดคำอธิบายประกอบจากไฟล์ ฉันกำลังโหลดจากมุมมอง:

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

แต่ PinView.Draw() ไม่เคยถูกเรียก!


person mshwf    schedule 23.12.2019    source แหล่งที่มา


คำตอบ (2)


เมธอด Draw จะถูกเรียกใช้หลังจากเมธอด ViewDidLoadเมื่อโหลดการควบคุมครั้งแรก ซึ่งระบบจะเรียกโดยอัตโนมัติ

ในกรณีของคุณ คุณไม่ได้ตั้งค่า Rect(Frame) ของ PinView ดังนั้นเมธอด Draw จะไม่ถูกเรียกใช้เพราะว่า Rect เป็นศูนย์ในค่าเริ่มต้น

ดังนั้นคุณจึงสามารถตั้งค่าเฟรมเริ่มต้นในตัวสร้างได้

public PinView()
{
  Frame = new CGRect (0,0,xx,xxx);
  ContentMode = UIViewContentMode.Redraw;
  SetNeedsDisplay();
}
person Lucas Zhang    schedule 23.12.2019
comment
มีความคิดบ้างไหมว่าทำไมมุมมองจึงปรากฏเป็นกล่องดำ ไม่มีการกำหนดสีดำ และมุมมองทำงานได้ดีเมื่อส่งผ่านไปยัง SetNativeControl ของตัวแสดงการควบคุมแบบกำหนดเอง - person mshwf; 23.12.2019
comment
คุณสามารถให้ตัวอย่างที่มีปัญหาเพื่อที่ฉันจะได้ทดสอบจากฝั่งของฉัน - person Lucas Zhang; 23.12.2019
comment
ฉันคิดว่าเพราะ UIColor.Black.SetStroke(); - person Lucas Zhang; 23.12.2019
comment
ในตัวอย่างที่แนบมาควรเป็น UIColor.Blue.SetStroke(); - person mshwf; 23.12.2019
comment
ฉันคิดว่า Draw ยังไม่โทรมา :( - person mshwf; 23.12.2019

ในกรณีของฉัน จำเป็นต้องเพิ่มมุมมองลงในลำดับชั้นของมุมมอง ให้กับ 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

person mshwf    schedule 23.12.2019
comment
อย่าลืมยอมรับคำตอบ ซึ่งจะช่วยผู้คนได้มากขึ้น :) - person Lucas Zhang; 23.12.2019
comment
คุณสามารถแก้ไขคำตอบพร้อมรายละเอียดเพิ่มเติมหรือแก้ไขคำตอบของฉันได้ บางทีทั้งสองคำตอบอาจคล้ายกัน - person Lucas Zhang; 24.12.2019