3

Xamarin.Forms コントロールを実装します。私が現在経験している問題Draw()は、カスタム レンダラーのオーバーライドされたメソッドが UI をブロックすることです (少なくとも iOS プラットフォームの場合)。私はグーグルで検索しましたが、成功しませんでした。UI をブロックせずにバックグラウンドで描画を実行することは可能ですか?

問題を示す 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
      { }
   }
}
4

1 に答える 1

0

そのための唯一の解決策は、時間のかかる描画と実際のコントロールでの描画を分離することです。

解決策は

  1. バックグラウンドで画像を生成します(イベントによってトリガーされます)。Draw メソッド内でのみ使用します。
  2. オーバーライドされた Draw メソッド内で生成された画像を使用します。

少なくとも私にとってはうまくいきます。

于 2016-04-21T13:05:32.363 に答える