4

アプリのプログレスバーを不確定ではなく確定として表示したいと思います。ただし、確定として設定する場合は機能しません(不確定の場合は問題なく機能します)。私はこれに対する他の答えのいくつかを読みましたが、それらは機能していませんどんな助けでもいただければ幸いです-ありがとう!

@interface AppDelegate : NSObject <NSApplicationDelegate> {

    IBOutlet NSProgressIndicator *showProgress;

}

- (IBAction)someMethod:(id)sender {

    [showProgress setUsesThreadedAnimation:YES];   // This works
    [showProgress startAnimation:self];            // This works
    [showProgress setDoubleValue:(0.1)];           // This does not work
    [showProgress setIndeterminate:NO];            // This does not work

    [self doSomething];
    [self doSomethingElse];
    [self doSomethingMore];
    ....

    [barProgress setDoubleValue:(1.0)];            // This does not work
    [barProgress stopAnimation:self];              // This works

}

更新されたコード[動作中]:

- (IBAction)someMethod:(id)sender {

    [showProgress setUsesThreadedAnimation:YES];
    [showProgress startAnimation:self];
    [showProgress setIndeterminate:NO];

    [showProgress setDoubleValue:(0.1)];
    [showProgress startAnimation:nil];

    dispatch_queue_t backgroundQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_async(backgroundQueue, ^{

        for (NSUInteger i = 0; i < 1; i++) {

            dispatch_async(dispatch_get_main_queue(), ^{
                [barProgress incrementBy:10.0];
            });
        }

    [self doSomething];

            [showProgress incrementBy:...];

        dispatch_async(dispatch_get_main_queue(), ^{

            [showProgress stopAnimation:nil];

        });
    });

    [showProgress setDoubleValue:(1.0)];
}
4

1 に答える 1

4

メソッドdoSomethingがメインスレッドをブロックしているため、実行ループが循環せず、UIの再描画がブロックされます。doSomething修正は、進行状況バーを更新するためにメインキューへの定期的なコールバックを使用して、バックグラウンドキューで長時間実行される作業を実行することです。

あなたのdoSomethingメソッドが何をするのか私にはわかりませんが、説明のために、100ステップのforループを実行すると仮定しましょう。次のように実装します。

- (void)doSomething
{
    [showProgress startAnimation:nil];
    dispatch_queue_t backgroundQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_async(backgroundQueue, ^{
        for (NSUInteger i = 0; i < 100; i++) {
            // Do whatever it is you need to do

            dispatch_async(dispatch_get_main_queue(), ^{
                [showProgress incrementBy:1.0];
            });
        }
        // Done with long running task
        dispatch_async(dispatch_get_main_queue(), ^{
            [showProgress stopAnimation:nil];
        });
    });
}

進行状況インジケーターを確定するように設定し、その値を初期化し、適切なminValueとmaxValueを設定する必要があることに注意してください。

メインスレッドで作業を行う必要がある場合は、doSomethingその作業の小さなチャンクを各実行ループサイクルで実行するようにスケジュールするか、作業中に実行ループを手動で定期的にスピンすることができますが、Grand Central Dispatch (GCD)を使用できれば、私の最初の選択肢になります。

于 2012-06-04T23:19:08.967 に答える