Jako następstwo reakcji Douga, tutaj jest to, co skończyło się z:
Każdy file
ma unikatowy identyfikator, więc zrobiłem to odpowiedzialny za wysyłanie powiadomień o aktualizacjach jego atrybutów (myślę KVO, ale bez kłopot):
Zrobiłem enum FileNotificationType
(tj. FileNotificationTypeDownloadTriggered
i FileNotificationTypeDownloadProgress
). Następnie wysłałbym postęp do NSNotification
's userInfo NSDictionary
wraz z 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];
});
}
Przedmiotem file
ma także sposób wyliczyć jakie rodzaje powiadomień mógł wysłać:
- (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;
}
Więc po aktualizacji atrybutem file
gdzie indziej, po prostu to zrobić:
NSDictionary *attributes = @{@"download_progress" : @(<PROGRESS_INTEGER>)};
[file_instance postNotificationWithType:FileNotificationTypeDownloadProgress andAttributes:attributes];
Po stronie odbiorcy mój delegat widoku tabeli zaimplementował te metody w celu dodania/usunięcia mojego niestandardowego UITableViewCells
jako obserwatorów Powiadomienia:
- (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];
}
Wreszcie zwyczaj UITableViewCell
musi implementować metodę 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;
}
}
Mam nadzieję, że to pomoże kogoś, kto chce zaktualizować komórki Tableview bez konieczności ich przeładować! Korzyścią z obserwacji wartości klucz-wartość jest to, że nie dostaniesz problemów, jeśli obiekt File
zostanie zwolniony z obserwowanej komórki. Nie muszę też dzwonić pod numer cellForRow...
.
Ciesz się!
Czy należy wyświetlać postępy w zakresie szczegółowości każdego punktu procentowego? Możesz po prostu monitorować postępy i przeładowywać komórki co 25%, czy coś w tym stylu? – BHendricks
To byłby awaryjny obiekt, jak sądzę. Aplikacja podcast na iOS radzi sobie z ciągłym postępem bez ponownego ładowania komórek. Zastanawiam się, jak to się robi ... – Christian
możesz również spróbować po prostu przekazać tylko drzewo widoku subview niestandardowej subview w komórce, która ma wskaźnik postępu? – BHendricks