Как следствие реакции Дага, вот что я в конечном итоге происходит с:
Каждый file
имеет уникальный идентификатор, так что я сделал его ответственным за регистрацию уведомления об обновлениях для его атрибутов (думаю, КВО, но без хлопот):
Я сделал переписку FileNotificationType
(т.е. FileNotificationTypeDownloadTriggered
и FileNotificationTypeDownloadProgress
). Затем я отправил бы прогресс в NSNotification
userInfo 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...
.
Наслаждайтесь!
Вам нужно будет показать прогресс в детализации каждого процентного пункта? Вы могли бы просто следить за прогрессом и только перезаряжать ячейки каждые 25% или что-то еще? – BHendricks
Это было бы отступлением, я полагаю. Приложение podcast iOS действительно хорошо показывает непрерывный прогресс без перезагрузки ячеек. Интересно, как это делается ... – Christian
вы также можете попробовать просто ретранслировать только дерево подзаголовки пользовательского subview внутри вашей ячейки, у которого есть индикатор прогресса? – BHendricks