Окно галереи изображений какао - PullRequest
0 голосов
/ 24 марта 2011

У меня есть панель 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, устанавливаю ее в представление, а затем вызываю нить sleep длянесколько секунд, прежде чем двигаться дальше.Проблема в том, что представление не будет перерисовываться с новым изображением, когда оно назначено.Я думал, что setNeedsDisplay: YES вызовет перерисовку, но когда-либо будет отображаться только первое изображение в коллекции.Я вставил NSLog () и отладил, и я точно знаю, что перечисление работает правильно, так как я могу видеть, что новая информация об изображении устанавливается так, как должно.это совершенно неправильный способ решения этой проблемы?

Спасибо,

Крейг

1 Ответ

1 голос
/ 24 марта 2011

Вы спите основной поток, который, я уверен, не очень хорошая идея. Я предлагаю, чтобы способ Какао сделать то, что вы хотите, это использовать таймер. Вместо вашего кода выше:

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

(Параметр userInfo позволяет передавать произвольный объект, который вы хотите использовать при срабатывании таймера, поэтому вы можете использовать его для отслеживания текущего индекса как номера NSN, но это должно быть обернут в объект изменяемого контейнера, потому что вы не можете установить его позже.)

Затем поместите код из вашего блока в метод, вызываемый таймером. Вам нужно будет создать переменную экземпляра для текущего индекса.

- (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];
...