2013-07-17 3 views
1

Я создаю приложение, которое показывает анимированный UIImageView как пользовательский способ указать, что приложение занято. Я использую NSOperationQueue для загрузки файлов, и я хотел бы показать UIImageView, когда в очереди есть что-то. Когда все операции в очереди завершаются, я хочу удалить UIImageView.Удалить анимацию UIImageView после завершения NSOperationQueue

Я думал, что это действительно легко сделать, но я застрял в последний час. Показать UIImageView очень просто, но я не могу его удалить. Это, наверное, что-то действительно простое, что я просто не замечаю. Вот мой код. Спасибо! :)

- (void)viewDidLoad { 
    //set up the uiimageview 
    self.spinnerView = [[UIImageView alloc] initWithFrame:CGRectMake([[UIScreen mainScreen] bounds].size.width-44,0,44,44)]; 
    self.spinnerView.animationImages = [NSArray arrayWithObjects: 
            [UIImage imageNamed:@"0.gif"], 
            [UIImage imageNamed:@"1.gif"], 
            [UIImage imageNamed:@"2.gif"], 
            [UIImage imageNamed:@"3.gif"], 
            [UIImage imageNamed:@"4.gif"], nil]; 
    self.spinnerView.animationDuration = 0.5f; 
    self.spinnerView.tag = 998; 
    self.spinnerView.animationRepeatCount = 0; 
    [self.view addSubview: self.spinnerView]; 

    //set up the queue 
    self.uploadQueue = [[NSOperationQueue alloc] init]; 
    [self.uploadQueue setMaxConcurrentOperationCount:1]; 

    //set up observer for the queue 
    [self.uploadQueue addObserver:self forKeyPath:@"operationCount" options:NSKeyValueObservingOptionNew context:NULL]; 
} 


- (void)newUpload:(NSData*)data { 
    [self.spinnerView startAnimating]; 
    //.... 
    //request is a NSURLRequest that's set up in this method 
    [NSURLConnection sendAsynchronousRequest:request queue:self.uploadQueue completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) { 
    }]; 
} 


- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object 
        change:(NSDictionary *)change context:(void *)context 
{ 
    if (object == self.uploadQueue && [keyPath isEqualToString:@"operationCount"]) { 
     if (self.uploadQueue.operationCount == 0) { 
      [self.spinnerView stopAnimating]; 
     } 
    } 
    else { 
     [super observeValueForKeyPath:keyPath ofObject:object 
          change:change context:context]; 
    } 

Выполняю ли я это правильно? Есть ли лучший способ сделать это? Я застрял здесь некоторое время, и я начинаю думать, что, возможно, это не UIImageView, а то, что я добавляю NSURLRequests к NSOperationQueue.

Еще раз спасибо!

+1

Я не вижу нигде в вашем коде, где вы удаляете счетчик. Если вы остановите анимацию, вы должны иметь [self.spinnerView removeFromSuperview]; – rdelmar

+0

Вы видели мой ответ? –

ответ

0

В документации для sendAsynchronousRequest:queue:completionHandler: указано, что операция добавлена ​​только в указанную операционную очередь после, асинхронный запрос URL-адреса завершен. Эта операция представляет собой только блок завершения.

Итак, я не думаю, что вы действительно добавляете операции добавления так, как планируете свою очередь. Запросы URL-адресов будут выполняться в собственных потоках вне очереди, а только очереди завершения будут помещены в очередь. Если вы не указали что-либо в самом блоке завершения, возможно, его даже не добавили в очередь?

В любом случае, я не думаю, что вы добавляете в очередь 5 операций URL-адреса, которые затем выполняются один за другим с помощью operationCount == 5, 4, 3, 2, 1, 0. Скорее всего, вы стреляете 5 одновременные запросы URL-адресов с их блоками завершения добавляются в очередь в неопределенной последовательности после завершения их запросов URL-адресов.


Для того, чтобы делать то, что я думаю, что вы собираетесь делать, вы могли бы:

  1. Написать «параллельный» NSOperation подкласс, который содержит и управляет NSURLConnection и NSURLRequest т.д.
  2. Использование AFNetworking.
  3. Продолжите с sendAsynchronousRequest:queue:completionHandler:, но воспользуйтесь обработчиком завершения одной операции, чтобы начать следующий запрос, и обработчик завершения окончательного запроса, чтобы остановить счетчик. Вы можете просто использовать основную очередь здесь, поскольку только выполняемая работа в очереди запускает следующую операцию или останавливает счетчик. Фактическая работа URL-запроса выполняется в любом потоке.

Написание собственного параллельного NSOperation немного сложно, я написал один сам, но я, вероятно, должен был просто использовать AFNetworking. Вариант 3, вероятно, самый быстрый, если он соответствует вашим потребностям.

0

Добавьте это в файл .h: UIImageView *spinnerView; В файле .m, вы хотели бы что-то подобное в вашей -(void)newUpload:

if (code that says file uploads are done) { 
spinnerView.hidden = YES; 
} 
2

Почему бы вам не попробовать https://github.com/samvermette/SVProgressHUD или https://github.com/jdg/MBProgressHUD? Они были сделаны именно для этой цели (показывая модальное окно загрузки при выполнении асинхронного задания). И они оба удобны в использовании и легко настраиваются для ваших изображений и многих других опций.