2015-03-27 2 views
-1

У меня возникла проблема с сохранением состояния UITableViewCell и не могу понять, как его решить. Надеюсь, кто-то может мне помочь.Проверить прогресс, где необходимо UITableView

Объяснение: Существует АНИ на сервере, и я получаю из него данные, а затем сохранить его в NSMutableArray. Каждый объект массива содержит свойство ready, которое может быть 1 или 0. Таким образом, у меня нет проблем с заполнением UITableView этими данными, но не каждый объект данных готов (т.е. 0), и мне нужно получить завершение работы на сервере, и после этого для его отображения в каждой ячейке это необходимо. У меня есть UIProgressView в динамическом прототипе UITableViewCell и установите прогресс после получения. Нет проблем, если такой «не готовый» объект является только одним. Но если есть много объектов, я не могу показать прогресс, и я не понимаю, почему.

Итак, вот мой код.

метод cellForRowAtIndexPath:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
static NSString *CellIdentifier = @"readyCell"; 
AVMMovieCell *cell = [self.readyTable dequeueReusableCellWithIdentifier:CellIdentifier]; 
    // Configure the cell... 
if (cell == nil) { 
    cell = (AVMMovieCell*)[tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 
} 
AVMFilmsStore *oneItem; 
oneItem = [readyArray objectAtIndex:indexPath.row]; 
NSNumber *rowNsNum = [NSNumber numberWithUnsignedInt:(unsigned int)indexPath.row]; 

if (oneItem.ready==1){ 
    cell.progressLabel.hidden = YES; 
    cell.progressLine.hidden = YES; 

if ([selecedCellsArray containsObject:[NSString stringWithFormat:@"%@",rowNsNum]] ) 
{ 

    if (![cell.progressLabel.text isEqualToString:@""]&& ![cell.progressLabel.text isEqualToString:@"Success"] && ![cell.progressLabel.text isEqualToString:@"Creating"]){ 
     cell.progressLabel.hidden = NO; 
     cell.progressLine.hidden = NO; 
    } else { 
     cell.progressLabel.hidden = YES; 
     cell.progressLine.hidden = YES; 
     } 
} 
else{ 
    if(!oneItem.isProcessing && !cell.selected){ 
    cell.progressLabel.hidden = YES; 
    cell.progressLine.hidden = YES; 
    } 
} 
} else { //if processing 
if (![processingCellsArray containsObject:[NSString stringWithFormat:@"%@",rowNsNum]]){ 
    [processingCellsArray addObject:[NSString stringWithFormat:@"%@",rowNsNum]]; 
    if (!cell.isSelected){ 

     [cell setSelected:YES]; 

    } 
    cell.progressLabel.hidden = NO; 
    cell.progressLine.hidden = NO; 

    NSArray * arrayOfThingsIWantToPassAlong = 
    [NSArray arrayWithObjects: cell, oneItem, indexPath, nil]; 

    if(!isMaking){ 
     [self performSelector:@selector(getProgress:) 
        withObject:arrayOfThingsIWantToPassAlong 
        afterDelay:0]; 
    } else{ 
    [self performSelector:@selector(getProgress:) 
       withObject:arrayOfThingsIWantToPassAlong 
       afterDelay:0.5]; 
    } 

    isMaking = YES; 

} else { 
    if (!cell.isSelected){ 
     [cell setSelected:YES]; 
    } 

    cell.progressLabel.hidden = NO; 
    cell.progressLine.hidden = NO; 

    NSArray * arrayOfThingsIWantToPassAlong = 
    [NSArray arrayWithObjects: cell, oneItem, indexPath, nil]; 

    if(!isMaking){ 
     [self performSelector:@selector(getProgress:) 
        withObject:arrayOfThingsIWantToPassAlong 
        afterDelay:0]; 
    } else{ 
    [self performSelector:@selector(getProgress:) 
       withObject:arrayOfThingsIWantToPassAlong 
       afterDelay:0.3]; 
    } 


    isMaking = YES; 
    } 

    } 
    return cell; 
} 

и метод getProgress:

-(void)getProgress:(NSArray*)args{ 

if (progManager == nil && !progStop){ 
    __block AVMFilmsStore * oneItem = args[1]; 
    if(!oneItem.isLocal){ 
     __block AVMMovieCell * cell = args[0]; 
     __block NSIndexPath *indexPath = args[2]; 
     progManager = [AFHTTPRequestOperationManager manager]; 
     __block NSString *token = [defaults objectForKey:@"token"]; 
     __block NSString *header = [NSString stringWithFormat:@"Bearer %@",token]; 
     __block NSDictionary *params = @{@"lang": NSLocalizedString(@"lang",nil),@"project":oneItem.fileId}; 
     __block NSString *oneHundredPercent; 
     __block NSString *progIsText; 

     progManager.responseSerializer = [AFJSONResponseSerializer serializer]; 
     [progManager.requestSerializer setValue:header forHTTPHeaderField:@"Authorization"]; 
     if(cell.selected || isMaking) { //if I just check for "cell.selected" is always "NO" 
      [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES]; 
      [progManager POST:@"http://example.com/api/project/get-progress" parameters:params success:^(AFHTTPRequestOperation *operation, id responseObject) { 
       if ([[responseObject objectForKey:@"result"]isEqualToString:@"success"]){ 
        progCreate = [responseObject objectForKey:@"progress"]; 

        oneHundredPercent = @"100"; 
        if ([progCreate intValue]==[oneHundredPercent intValue]){ 
         if([processingCellsArray containsObject:[NSString stringWithFormat:@"%ld",(long)indexPath.row]]){ 
          [processingCellsArray removeObject:[NSString stringWithFormat:@"%ld",(long)indexPath.row]]; 
          [cell setSelected:NO]; 

         } 
         [readyArray removeAllObjects]; 
         [defaults setObject:@"false" forKey:@"isSomethingInSort"]; 
         isMaking = NO; 
         [self getReadyMovies:progIsText nameLabel:oneItem.fileName]; 

        } else{ 
         if([progCreate intValue]>=50){ 
          if([progCreate intValue]>=60){ 
           self.navigationController.navigationItem.leftBarButtonItem.enabled = YES; 
           createMainButton.enabled = YES; 
          } 
          [[NSNotificationCenter defaultCenter] postNotificationName:@"gotFiftyNote" object:@"50"]; 
          [cell.progressLine setProgress:[progCreate floatValue]/100 animated:YES]; 
         } else { 
          [cell.progressLine setProgress:progUploadLimit]; 
         } 
         progManager = nil; 
         progManager.responseSerializer = nil; 
         progManager.requestSerializer = nil; 
         token = nil; 
         header = nil; 
         params = nil; 
         progIsText = nil; 
         oneItem = nil; 
         cell = nil; 
         indexPath = nil; 
         isMaking = YES; 
         progCreate = nil; 
         oneHundredPercent = nil; 

         [self getProgress:args]; 
        } 
       } 
      } failure:^(AFHTTPRequestOperation *operation, NSError *error) { 
       [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO]; 
       NSLog(@"Error: %@", error.localizedDescription); 
      }]; 

     } 

    } 
    } 
} 

Любые предложения будут полезны для меня. У меня головная боль в течение двух недель с этой проблемой.

+1

Вам необходимо реорганизовать этот код и охватить ориентацию объекта. Сделайте ячейку ответственной за само обновление. 'performSelector' почти всегда является запахом кода. У вас также будут проблемы, потому что вы обновляете пользовательский интерфейс от фонового обработчика и потенциальных проблем с нетекающими обновлениями для NSMutableArray. – Paulw11

+0

У меня была такая же проблема несколько дней назад. Проверьте комментарий Роба и пример Аарона. Это может помочь вам: [link] (http://stackoverflow.com/questions/29202212/uiprogressview-on-uitableviewcell) – TienLe

ответ

0

Я вижу ваш код, но его сложно отслеживать с помощью этих больших методов. Я бы не стал отслеживать обработки ячеек в массиве. Каждая ячейка имеет объект для представления, у этого объекта есть значение bool ready и значение прогресса, верно ?. Поэтому попробуйте что-нибудь вроде этого:

  • Убедитесь, что каждая из ваших ячеек имеет progressView в качестве подсмотра.
  • Ваш класс ячейки должен иметь общедоступный метод с именем styleForReady: (bool) isReady andProgress: (nsinteger) progress
  • Сделайте вызов службы, чтобы узнать, выполнены ли они или нет, для каждой модели. Всякий раз, когда этот служебный вызов возвращается, вы просто обновляете объекты модели в массиве, и после того, как у них есть новые значения прогресса, вы делаете [self.tableView reloadData]. Это приведет к вызову numberOfRows (который должен возвращать arrayOfObjects.count) и cellForRowAtIndexPath: (который должен деактивировать ячейку для этого indexPath, захватить модель, представляющую эту ячейку, что-то вроде arrayOfObjects [indexPath.row] и, наконец, вызвать ячейку для стиля на основе этой модели делает [клетка styleForReady: objectModel.ready andProgress: objectModel.progress])

Имейте в виду, что контроллер должен только следить за модельными объектами, Dequeue клетки и скажите клетку стиль прохождения модель. Не ставьте всю логику в контроллер.

+0

спасибо за отзыв! не понял один момент: где я должен получить прогресс каждого объекта сейчас? в классе 'objectModel' или в классе ячеек? Вы имеете в виду, что я должен реализовать свой метод getProgress в подклассе 'UITableViewCell'? – vendettacore

+0

Контроллер отвечает за модель. Каждая модель (подкласс NSObject, должна иметь прогресс и готова как свойства). Ячейка отвечает за рисование, вы должны иметь метод styleWithProgress: andReady: в своей ячейке, который будет отвечать за обновление progressView на основе новых результатов и готовых значений из модели. Когда запрос о прогрессе возвращается, вы обновляете модели (а не ячейку), а затем вызываете reloadData, что вызовет все методы пользовательского интерфейса, необходимые для рисования tableViewCells на основе новых обновленных моделей. – Pauls

+0

ok Я реализовал метод 'getProgress' в моем классе модели (подкласс NSObject) и при каждом вызове этого метода я изменяю значение этого свойства класса readyProgress, также я реализовал метод' - (void) styleForReady: (BOOL) isReady andProgress: (float) progress' (мне нужно значение float для него .. не имеет значения, а теперь в моей 'cellForRowAtIndexPath' я проверяю объекты, которые не готовы, а затем вызывает' [cell styleForReady: NO andProgress: [oneItem getProgress ]] ;, но я не понимаю, где я должен был бы называть '[self.tableView reloadData], поэтому я могу видеть изменения только при прокрутке – vendettacore

Смежные вопросы