Обновить cellForRowAtIndexPath progressView

#objective-c #uitableview #grand-central-dispatch #nsoperationqueue #nsobject

#objective-c #uitableview #большая центральная диспетчерская #nsoperationqueue #nsobject

Вопрос:

У меня есть NSObject, который содержит загрузку. Одним из свойств является fileProgress (float).

Прогресс обновляется с помощью NSURLSessionDelegateMethod именованного URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didSendBodyData:(int64_t)bytesSent totalBytesSent:(int64_t)totalBytesSent totalBytesExpectedToSend:(int64_t)totalBytesExpectedToSend .

Объекты загрузки обновляются должным образом с помощью taskIdentifier .

В другом классе у меня есть UITableView с пользовательской UITableViewCell, которая имеет progressView . Я хотел бы обновить progressView с помощью текущего fileProgress.

Когда загрузка завершена в классе NSObject, загрузка удаляется и вызывается метод делегата, чтобы сообщить делегатам, что произошло изменение количества очередей. По мере удаления загрузок просмотр прогресса изменяется на этот момент времени.

Как я могу передать ссылку на текущее представление хода выполнения ячеек, чтобы выполнить progressview обновление?

Я пытался добавить в свой cellForRowAtIndexPath , но это, похоже, не работает.

 [[NSOperationQueue mainQueue] addOperationWithBlock:^{
         cell.progressView.progress = item.fileProgress;
         cell.lblProgress.text = [NSString stringWithFormat:@"%.1f%%", (item.fileProgress * 100) ];
    }];
  

Я здесь немного потерялся. Любая помощь?

Загрузить элемент

     @interface AMUploadItem : NSObject <NSCoding>
    @property float  fileProgress; //The fractional progress of the uploaded; a float between 0.0 and 1.0.
@property (nonatomic, strong) NSURLSessionUploadTask *uploadTask; //A NSURLSessionUploadTask object that will be used to keep a strong reference to the upload task of a file.
@property (nonatomic) unsigned long taskIdentifier;
    @end
  

Пользовательский tableViewCell.h (Пустой .m)

 @interface ItemTableViewCell : UITableViewCell
@property (weak, nonatomic) IBOutlet UILabel *lblProgress;
@property (weak, nonatomic) IBOutlet UIProgressView *progressView;
@end
  

Контроллер представления таблицы

  - (void)viewDidLoad {
    [super viewDidLoad];
    _manager = [AMPhotoManager sharedManager];
    _manager.delegate = self;    

}

 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return [_manager getQueueCount];
}


 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    static NSString *simpleTableIdentifier = @"cellUpload";

    ItemTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];

    if (cell == nil) {
        cell = [[ItemTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
    }

    AMUploadItem * item = [_manager listImagesInQueue][indexPath.row];

 //THIS DOENS'T WORK
    [[NSOperationQueue mainQueue] addOperationWithBlock:^{
         cell.progressView.progress = item.fileProgress;
         cell.lblProgress.text = [NSString stringWithFormat:@"%.1f%%", (item.fileProgress * 100) ];
    }];

    return cell;
}
  

Класс manager просто содержит массив AMItemUploads и NSURLSessionUploadTask делегатов.

Ответ №1:

Это может быть излишним для вашей ситуации, но вот что я сделал в аналогичной ситуации. Передача ссылок на представления / ячейки опасна, поскольку время ожидания передачи может истечь или стать устаревшим из-за взаимодействия с пользователем. Вместо этого вы должны передавать уникальные идентификаторы представлениям / ячейкам, а затем просматривать их по мере необходимости, чтобы обновить их прогресс. Пользователи становятся нетерпеливыми в ожидании завершения передачи и предполагают, что они могут удалять файлы и другие неприятные вещи во время ожидания.

     // this is pseudo code at best
    URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didSendBodyData:(int64_t)bytesSent totalBytesSent:(int64_t)totalBytesSent totalBytesExpectedToSend:(int64_t)totalBytesExpectedToSend
    {
          NSString *uniqueID = <something unique from your NSURLSession >

          [[NSOperationQueue mainQueue] addOperationWithBlock:^{
              // assuming you can get the global instance of your controller here.
              [myController updateProgress:uniqueID];

    }

- (void) updateProgress: (NSString *)uniqueID
{
              NSArray *filesDataSource = <get your dataSource here> ;
              for ( ContentTableRow *fileRow in filesDataSource )
              {            
                 if ( [fileRow.uniqueID isEqualToString: uniqueID] )
                 {
                     // update progress
                 }
              }
           }
}