不从自定义 UIView 调用绘制方法
Draw method doesn't get called from the custom UIView
我正在为 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
派生的 class,我在其中绘制注释路径:
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()
永远不会被调用!
方法Draw
将在方法ViewDidLoad
第一次加载控件时调用,由系统自动调用。
在您的情况下,您没有设置 PinView
的 Rect(Frame)。所以方法 Draw
将永远不会被调用,因为 Rect
默认为零。
所以你可以在构造函数中设置默认框架
public PinView()
{
Frame = new CGRect (0,0,xx,xxx);
ContentMode = UIViewContentMode.Redraw;
SetNeedsDisplay();
}
视图需要添加到视图层次结构中,在我的例子中,添加到 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
方法。
我正在为 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
派生的 class,我在其中绘制注释路径:
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()
永远不会被调用!
方法Draw
将在方法ViewDidLoad
第一次加载控件时调用,由系统自动调用。
在您的情况下,您没有设置 PinView
的 Rect(Frame)。所以方法 Draw
将永远不会被调用,因为 Rect
默认为零。
所以你可以在构造函数中设置默认框架
public PinView()
{
Frame = new CGRect (0,0,xx,xxx);
ContentMode = UIViewContentMode.Redraw;
SetNeedsDisplay();
}
视图需要添加到视图层次结构中,在我的例子中,添加到 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
方法。