3

I implement a Xamarin.Forms control. The problem I'm currently experiancing is that an overridden Draw() method of a custom renderer blocks UI (at least for iOS platform). I've googled but with no success. Is is possible to perform the drawing in a background without blocking the UI?

Here is the code of a simple renderer for iOS platform that that demonstrates the issue.

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
      { }
   }
}
Moin Shirazi
  • 4,372
  • 2
  • 26
  • 38
zavolokas
  • 697
  • 1
  • 5
  • 20

1 Answers1

0

Looks like that the only solution for that is to separate the time consuming drawing and drawing on the actual control.

The solution is

  1. to generate an image in a background(triggered by an event). and only than use it within the Draw method.
  2. to use the generated image within the overridden Draw method.

At least it works for me.

zavolokas
  • 697
  • 1
  • 5
  • 20