2

情報を照会するプロセスがあり、UIViewController で受け取った情報を画面に表示したいと考えています。私がやりたいのは、このようなオーバーレイを使用することです

https://github.com/xamarin/mobile-samples/blob/master/MWC/MWC.iOS/UI/Controls/LoadingOverlay.cs

loadingLabel.TextUIViewController から更新します。ただし、このビューを追加してもすぐには機能しないようです。グラフィックが更新される前に関数呼び出しを終了する必要があると思います。

このタイプのオーバーレイを表示し、データの処理中に「実行」できるようにする方法は何ですか? 呼び出しを別のスレッドに移動し、デリゲート関数を使用して表示を更新する必要がありますか?

4

3 に答える 3

2

UIKit が画面を更新するには、コードでメイン ループを実行する必要があります。メイン ループを実行する簡単な方法は、いくつかのコードを実行して制御を返すことです。これにより、既存のループが実行され、イベント (タイマー、入力、表示の変更) が処理されます。

あなたができることがいくつかあります:

  • ブロッキング操作をバックグラウンドで実行してから、InvokeOnMainThread を使用して UI を更新します。これは、アプリが常にメイン ループを実行していることを意味しますが、ときどきバックグラウンド スレッドが何らかのコードの実行を要求します (ステータスの表示など)。

  • アプリケーションの途中でメイン ループを手動で実行します。これは本当に良い考えではありませんが、いくつかの非常に限られたケースで機能します。この質問の私の答えを参照してください: UIAlertView は待機しません

于 2013-06-21T13:59:50.957 に答える
2

再読とジェイソンのコメントの後、おそらく次のようなことをしたいと思うでしょう:

        Task.Factory.StartNew (() => {

            //Do Process intensive things here

            for (int i = 0; i < 999999999; i++) {
                System.Threading.Thread.Sleep(1000);

                this.InvokeOnMainThread(() =>
                                        {
                    this.MyLabel.Text == string.Format("Counted to {0}", i);
                });
            }
        });

基本的に、UI を更新する場合は常にメイン スレッドで行う必要があります。

于 2013-06-20T21:28:52.153 に答える
0

Alpha チャネルから Xamarin.iOS を実行する余裕がある場合は、C#5 async/await にアクセスできます。タスクとコールバックの複雑さをうまく隠しています。

public override void ViewDidLoad ()
{
    base.ViewDidLoad ();
    muButton.TouchUpInside += DoSomething;
}

async void DoSomething (object o, EventArge e)
{
    myLabel.Text = "Starting";
    for (var i = 0; i<10;i++)
    {
        await ProcessPart(i);
        myLabel.Text = String.Format ("Progress : {i}0%", i+1);
    }

    myLabel.Text = "Done";
}

Task ProcessPart (int i)
{
    Task.Delay (1000);
}

あなたの処理がそれ自体の進行状況を報告するのに十分なほどスマートである場合、その署名をに変更して、次のIEnumerable<Task<int>> Process ()ような素敵な更新ループを作成できます。

async void DoSomething (object o, EventArge e)
{
    foreach (var tp in Process())
        myLabel.Text = String.Format ("Progress : {i}0%", await tp +1);
}

ダミーの Process() 関数は次のようになります。

IEnumerable<Task<int>> Process ()
{
    for (var i=0; i<10; i++)
        yield return Task.Delay (1000).ContinueWith(x => i);
}
于 2013-06-21T14:00:30.817 に答える