2015-04-26 4 views
5

Предположим, у вас есть UITableView, который отображает список file метаданных, и вы хотите показать download_progress каждого файла в UILabel пользовательского UITableViewCell. (Это произвольно длинный список, поэтому динамические ячейки будут повторно использоваться).iOS- Обновить информацию UITableViewCell без перезагрузки строки?

Если вы хотите обновить ярлык, не звонив ни reloadData, ни reloadRowsAtIndexPaths, как вы можете это сделать?

Для тех, кто задается вопросом - я не хочу вызывать ни один из методов reload..., потому что нет необходимости перезагружать всю ячейку для каждого обновления процентной точки на download_progress.

Единственное решение я попадались являются:

  • Добавление ячейки как ключ-значение наблюдателя для file «s download_progress.

  • Вызов cellForRowAtIndexPath... непосредственно, чтобы получить ярлык и изменить его текст.

Однако KVO вообще не весело апи работать - и даже меньше, так что при добавлении повторного использования клеток в смеси. Вызов cellForRowAtIndexPath напрямую при каждом добавлении процентного пункта кажется грязным.

Итак, каковы возможные решения? Любая помощь будет оценена по достоинству.

Спасибо.

+0

Вам нужно будет показать прогресс в детализации каждого процентного пункта? Вы могли бы просто следить за прогрессом и только перезаряжать ячейки каждые 25% или что-то еще? – BHendricks

+0

Это было бы отступлением, я полагаю. Приложение podcast iOS действительно хорошо показывает непрерывный прогресс без перезагрузки ячеек. Интересно, как это делается ... – Christian

+0

вы также можете попробовать просто ретранслировать только дерево подзаголовки пользовательского subview внутри вашей ячейки, у которого есть индикатор прогресса? – BHendricks

ответ

2

Как следствие реакции Дага, вот что я в конечном итоге происходит с:

Каждый file имеет уникальный идентификатор, так что я сделал его ответственным за регистрацию уведомления об обновлениях для его атрибутов (думаю, КВО, но без хлопот):

Я сделал переписку FileNotificationType (т.е. FileNotificationTypeDownloadTriggered и FileNotificationTypeDownloadProgress). Затем я отправил бы прогресс в NSNotificationuserInfo NSDictionary вместе с FileNotificationType.

- (void)postNotificationWithType:(FileNotificationType)type andAttributes:(NSDictionary *)attributes 
{ 
    NSString *unique_notification_id = <FILE UNIQUE ID>; 

    NSMutableDictionary *mutable_attributes = [NSMutableDictionary dictionaryWithDictionary:attributes]; 
    [mutable_attributes setObject:@(type) forKey:@"type"]; 

    NSDictionary *user_info = [NSDictionary dictionaryWithDictionary:mutable_attributes]; 

    dispatch_async(dispatch_get_main_queue(), ^{ 
    [[NSNotificationCenter defaultCenter] postNotificationName:unique_notification_id object:nil userInfo:user_info]; 
    }); 
} 

Объект file также есть метод для перечисления, какие типы уведомлений он может отправить:

- (NSArray *)notificationIdentifiers 
{ 
    NSString *progress_id = <FILE UNIQUE ID + FILENOTIFICATIONTYPE>; 
    NSString *status_id = <FILE UNIQUE ID + FILENOTIFICATIONTYPE> 
    NSString *triggered_id = <FILE UNIQUE ID + FILENOTIFICATIONTYPE> 

    NSArray *identifiers = @[progress_id, status_id, triggered_id]; 
    return identifiers; 
} 

Итак, когда вы обновить атрибут file в другом месте, просто сделать это:

NSDictionary *attributes = @{@"download_progress" : @(<PROGRESS_INTEGER>)}; 
[file_instance postNotificationWithType:FileNotificationTypeDownloadProgress andAttributes:attributes]; 

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

- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    File *file = [modelObject getFileAtIndex:indexPath.row]; 
    for (NSString *notification_id in file.notificationIdentifiers) 
    { 
     [[NSNotificationCenter defaultCenter] addObserver:cell selector:@selector(receiveFileNotification:) name:notification_id object:nil]; 
    } 
} 

- (void)tableView:(UITableView *)tableView didEndDisplayingCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    [[NSNotificationCenter defaultCenter] removeObserver:cell]; 
} 

Наконец, обычай UITableViewCell должно реализовать receiveFileNotification: метод:

- (void)receiveFileNotification:(NSNotification *)notification 
{ 
    FileNotificationType type = (FileNotificationType)[notification.userInfo[@"type"] integerValue]; 

    // Access updated property info with: [notification.userInfo valueForKey:@"<Your key here>"] 

    switch (type) 
    { 
     case FileNotificationTypeDownloadProgress: 
     { 
      // Do something with the progress 
      break; 
     } 
     case FileNotificationTypeDownloadStatus: 
     { 
      // Do something with the status 
      break; 
     } 
     case FSEpisodeNotificationTypeDownloadTriggered: 
     { 
      // Do something if the download is triggered 
      break; 
     } 
     default: 
      break; 
    } 
} 

Надеется, что это помогает кто-то ищет, чтобы обновить Tableview клетку без необходимости загружать их! Преимущество над наблюдением за ключевыми значениями заключается в том, что вы не получите проблем, если объект File освобождается от ячейки, которая все еще наблюдает. Мне также не нужно звонить cellForRow....

Наслаждайтесь!

1

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

+0

Да, я могу попробовать NSNotification с уникальным идентификатором файла в качестве имени. Где в жизненном цикле клетки вы думали о добавлении/удалении ячейки в качестве наблюдателя? Добавить в 'tableviewWillDisplayCell ...' и удалить в' tableviewDidEndDisplayingCell ... '? – Christian

+0

У меня не было так далеко, но ваше предложение, вероятно, довольно хорошее место для этого. –

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