Переопределенный метод Draw пользовательского интерфейса блоков ViewRenderer
Я реализую элемент управления Xamarin.Forms. Проблема, которую я сейчас испытываю, заключается в том, что Draw()
метод пользовательского рендерера блокирует пользовательский интерфейс (по крайней мере, для платформы iOS). Я гуглил, но безуспешно. Можно ли выполнять рисование в фоновом режиме, не блокируя пользовательский интерфейс?
Вот код простого рендерера для платформы iOS, который демонстрирует проблему.
public class MyCustomRenderer : ViewRenderer
{
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged(sender, e);
SetNeedsDisplay();
}
public override void Draw(CoreGraphics.CGRect rect)
{
var myControl = (MyControl)this.Element;
if (!myControl.IsRendered)
{
using (var context = UIGraphics.GetCurrentContext())
{
var token = CancellationToken.None;
var task = Task.Factory.StartNew(() => TimeConsumingRendering(context, token), token);
// task.Wait() blocks the UI but draws the desired graphics.
// When task.Wait() is commented out = the desired graphics doesn't get drawn and it doesn't block the UI
task.Wait();
}
}
}
private void TimeConsumingRendering(CGContext context, CancellationToken token)
{
try
{
for (int i = 0; i <= 100; i++)
{
token.ThrowIfCancellationRequested();
var delay = Task.Delay(50);
delay.Wait();
}
context.ScaleCTM(1f, -1f);
context.TranslateCTM(0, -Bounds.Height);
context.SetTextDrawingMode(CGTextDrawingMode.FillStroke);
context.SelectFont("Helvetica-Bold", 16f, CGTextEncoding.MacRoman);
context.SetFillColor(new CoreGraphics.CGColor(1f, 0f, 0f));
context.ShowTextAtPoint(0, 0, "Finished");
}
catch
{ }
}
}
1 ответ
Решение
Похоже, что единственное решение для этого состоит в том, чтобы отделить трудоемкий рисунок и рисунок на фактическом элементе управления.
Решение
- генерировать изображение в фоновом режиме (вызвано событием). и только потом использовать его в методе Draw.
- использовать сгенерированное изображение в переопределенном методе Draw.
По крайней мере, это работает для меня.