Обновите UIProgressView на UITableViewCell

На данный момент у меня есть основное табличное представление с ячейками, которые загружаются из XML и заполняются. После этого я могу щелкнуть одну ячейку и загрузить подробный вид (файл xib, загруженный с помощью кода в основном виде таблицы). В подробном окне я могу нажать кнопку загрузки, и некоторые файлы загружаются асинхронно в папку документов. Затем я открываю вид и снова вижу свой стол.

Моя идея сейчас состоит в том, чтобы увидеть ход загрузки в ячейке таблицы. Я настроил uiprogressview для каждой ячейки, который по умолчанию скрыт. Теперь я хочу видеть индикатор выполнения при запуске загрузки. Как я могу это сделать?

Я попробовал что-то с executeSelectorOnMainThread и селектором, которые изменяют прогресс моей выбранной ячейки (которую я назначаю в основном виде таблицы). Кажется, плохая идея - не сработало.

Некоторые идеи, как это сделать?


РЕДАКТИРОВАТЬ 2: Часть кода моего решения, ВНИМАНИЕ! Это не настоящий код, я удалил много строк для вставки сюда. Есть не все релизы и т.д. Я думаю, что решение действительно грязное, но я не нашел лучшего решения для меня...

Некоторые важные вещи:

  • cellDownloading: Массив, который знает каждую ячейку, которая загружается в данный момент.
  • progressDictionary: знает ход каждой ячейки
  • cellDictionary: знает каждую ячейку, заполненную делегатом cellForRowAtIndexpath табличного представления

Я также не могу скопировать весь код, потому что есть много вещей, которые не имеют ничего общего со всем процессом, но я даю вам важные шаги. Мои ячейки создаются путем разбора xml, поэтому у каждой ячейки есть setId в моем случае.

////////////////// // Downloader.mm ////////////////////

способ скачать асинхронный

-(void)startAsynchronousDownload:(NSString*)path{    

// generate notification
NSMutableDictionary *userInfo = [[NSMutableDictionary alloc] init];
NSNumber *tmpSetId = [NSNumber numberWithInteger:setId];

[userInfo setObject:tmpSetId forKey:@"setId"];

NSNotification* notification = [NSNotification notificationWithName:@"downloadStackNotification" object:self userInfo:userInfo];  
[[NSNotificationCenter defaultCenter] postNotification:notification];  

// add some infos...
NSMutableDictionary *dictionary = [[NSMutableDictionary alloc] init];
[dictionary setObject:tmpSetId forKey:@"setId"];
// perhaps more here

// asynchronous download handling
NSOperationQueue *queue = [NSOperationQueue alloc] init];
NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(downloadImagesWithDictionary:) object:dictionary];

// release
[operation release];
[dictionary release];
[userInfo release];
}

В моем примере селектор downloadImagesWithDictionary загружает несколько изображений, для каждого загруженного изображения я отправляю уведомление. В моем случае каждая стопка изображений имеет setId.

[...]
    NSMutableDictionary *userInfo = [[NSMutableDictionary alloc] init];
    NSNumber *sliceCounter = [NSNumber numberWithInt:i];
    NSNumber *amount = [NSNumber numberWithInt:amountOfImages];
    NSNumber *tmpSetId = [NSNumber numberWithInteger:setId];

    [userInfo setObject:sliceCounter forKey:@"actualImage"];
    [userInfo setObject:amount forKey:@"allImages"];
    [userInfo setObject:tmpSetId forKey:@"setId"];
    NSNotification* notification = [NSNotification notificationWithName:@"downloadSliceNotification" object:self userInfo:userInfo];  
    [[NSNotificationCenter defaultCenter] postNotification:notification ];  
[...]

//////////////////////////// // TableViewController.mm ///////////////////// ///////////

Теперь нам нужно получить уведомления, чтобы обновить нашу таблицу

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(downloadSliceNotification:) name:@"downloadSliceNotification" object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(downloadStackNotification:) name:@"downloadStackNotification" object:nil];

Нам нужен словарь ячеек, чтобы знать весь путь индекса существующих ячеек таблицы. Заполните их в делегате cellForRowAtIndexPath

[cellDictionary setObject:indexPath forKey:[NSString stringWithFormat:@"%d",cellSetId]];

Теперь мы создаем обработчик, который делает что-то, если мы получаем уведомление. Сначала обработчик, если загрузка начинается, у меня есть словарь прогресса, который знает каждый прогресс каждой ячейки, и я могу идентифицировать каждую ячейку по setId - возможно, вам придется немного это изменить. немного

- (void)downloadStackNotification:(NSNotification*)notification {  
NSDictionary *userInfo = [notification userInfo];
NSNumber *setId = [userInfo objectForKey:@"setId"];

NSNumber *progress = [NSNumber numberWithInt:0];    
[progressDictionary setObject:progress forKey:[setId stringValue]];

// add cell to downloadlist
[cellDownloading addObject:[setId stringValue]];

}

Теперь для каждого шага загрузки (в моем случае одно изображение). Рассчитать процесс и обновить словарь, получить ячейку для обновления прогресса

- (void)downloadSliceNotification:(NSNotification*)notification {  
NSDictionary *userInfo = [notification userInfo];
NSNumber *sliceCounter = [userInfo objectForKey:@"actualImage"];
NSNumber *amount = [userInfo objectForKey:@"allImages"]; 
NSNumber *setId = [userInfo objectForKey:@"setId"]; 

NSNumber *progress = [NSNumber numberWithFloat:(100/[amount floatValue])*[sliceCounter floatValue]];      

[progressDictionary setObject:progress forKey:[setId stringValue]];
NSIndexPath* indexPath = [cellDictionary objectForKey:[setId stringValue]];

CustomServerCell* cell = (CustomServerCell*)[self.tableView cellForRowAtIndexPath:indexPath];
NSMutableDictionary *downloadData = [[NSMutableDictionary alloc] init];
[downloadData setObject:cell forKey:@"cell"];
[downloadData setObject:sliceCounter forKey:@"actualImage"];
[downloadData setObject:amount forKey:@"allImages"];

[self performSelectorOnMainThread:@selector(updateProgressWithDictionary:) withObject:downloadData waitUntilDone:NO];
} 

Обновить ячейку

-(void)updateProgressWithDictionary:(NSMutableDictionary*)downloadData {

CustomServerCell* cell = (CustomServerCell*)[downloadData objectForKey:@"cell"];
NSNumber *sliceCounter = [downloadData objectForKey:@"actualImage"];
NSNumber *amount = [downloadData objectForKey:@"allImages"];

cell.progressView.hidden = FALSE;
NSNumber *tmpProgress = [progressDictionary objectForKey:[NSString stringWithFormat:@"%d",cell.progressView.tag]];
cell.progressView.progress = [tmpProgress floatValue]/100;
cell.statusLabel.text = [NSString stringWithFormat:@"download slice %d / %d",[sliceCounter integerValue],[amount integerValue]];

}

2 ответа

Решение

Я понял проблему. Поскольку я использую tableviewcells, которые читаются из XML через Интернет, у меня были некоторые проблемы с перезагрузкой tableview. Я добился успеха в следующем процессе:

  1. Создать уведомление для каждого шага загрузки (в моем случае я загружаю срез за срез)
  2. Зарегистрировать наблюдателя в основном классе просмотра таблиц
  3. Создать обработчик для уведомления
  4. Отправить информацию о загрузке в виде словаря userinfo в уведомлении
  5. Сохранение прогресса каждого порядка загрузки в словаре с идентификатором в качестве ключа (в моем случае установленный идентификатор)
  6. Создайте селектор, прочитайте словарь и установите процесс в правой ячейке.
  7. Добавьте селектор в executeSelectorOnMainThread

Не знаю, если это хорошее решение - но оно работает для меня.

Попробуйте использовать

[self performSelectorOnMainThread:@selector(updateProgressBar:) withObject: [NSNumber numberWithFloat:pr] waitUntilDone: YES] 

вместо

progressView.progress += 0.1; // or any other number for that matter 
Другие вопросы по тегам