0

アプリに HUD パネルがあり、一連の画像を取得して、次の画像を表示する前に、パネルに各画像を数秒間表示できるようにしたいと考えています。私はココアに非常に慣れていないため、これを実装するのに問題があるため、いくつかの指針を歓迎します. これが私が現在試していることです:

[newShots enumerateObjectsUsingBlock:^(NSDictionary *obj, NSUInteger idx, BOOL *stop) 
 {
     //get url
     NSURL *imageUrl = [[NSURL alloc] initWithString:[obj objectForKey:@"image_url"]];;

     //get image from url
     NSImage *image = [[NSImage alloc] initWithContentsOfURL:imageUrl];

     //set it to shot panel
     [shotPanelImageView setImage:image]; 

     //clean up
     [imageUrl release];
     [image release];

     //set needs refresh
     [shotPanelImageView setNeedsDisplay:YES];

     //sleep a few before moving to next
     [NSThread sleepForTimeInterval:3.0];
 }]; 

ご覧のとおり、各画像の情報をループして、URL 経由で画像を取得し、ビューに設定してから、次に進む前に数秒間スレッド スリープを呼び出しています。問題は、ビューが割り当てられたときに新しいイメージで再描画されないことです。setNeedsDisplay:YES は再描画を強制すると思いましたが、コレクションの最初の画像しか表示されません。私は NSLog() を入れてデバッグしましたが、新しい画像情報が適切に設定されていることを確認できるため、列挙が正しく機能していることを確認しています。

私が見逃しているものはありますか、それともこの問題を解決するための完全に間違った方法ですか?

ありがとう、

クレイグ

4

1 に答える 1

1

あなたはメインスレッドを寝かせていますが、これは良い考えではないと確信しています。あなたが望むことを行うココアの方法は、タイマーを使用することです。上記のコードの代わりに:

[NSTimer scheduledTimerWithTimeInterval:3.0
                                 target:self
                               selector:@selector(showNextShot:)
                               userInfo:nil
                                repeats:YES];

(userInfoパラメーターを使用すると、タイマーが起動したときに使用する任意のオブジェクトを渡すことができるため、これを使用して現在のインデックスを NSNumber として追跡することができますが、変更可能なコンテナー オブジェクトにラップする必要があります。 、後で設定できないためです。)

次に、ブロックのコードをタイマーによって呼び出されるメソッドに入れます。現在のインデックスのインスタンス変数を作成する必要があります。

- (void)showNextShot:(NSTimer *)timer {
    if( currentShotIdx >= [newShots count] ){
        [timer invalidate]; // Stop the timer
        return;    // Also call another cleanup method if needed
    }
    NSDictionary * obj = [newShots objectAtIndex:currentShotIdx];
    // Your code...
    currentShotIdx++;
}

タイマーの使用による最初の 3 秒の遅延を回避するには、タイマーを設定する直前に、タイマーが使用するのと同じメソッドを呼び出すことができます。

[self showNextShot:nil]
[NSTimer scheduled...

または、繰り返しのないタイマーをできるだけ早く起動するようにスケジュールすることもできます (本当に を使用したい場合userInfo):

[NSTimer scheduledTimerWithTimeInterval:0.0
                                      ...
                                repeats:NO];

編集:私は忘れていました-initWithFireDate:interval:target:selector:userInfo:repeats:

NSTimer *tim = [[NSTimer alloc] initWithFireDate:[NSDate date]
                                        interval:3.0
                                          target:self
                                        selector:@selector(showNextShot:)
                                        userInfo:nil
                                         repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:tim 
                             forMode:NSDefaultRunLoopMode];
[tim release];
于 2011-03-24T20:12:25.707 に答える