2015-04-26 18 views
5

Załóżmy, że masz UITableView, który wyświetla listę metadanych file i chcesz pokazać download_progress każdego pliku w postaci UILabel niestandardowego UITableViewCell. (Jest to lista arbitralnie długa - w ten sposób dynamiczne komórki zostaną ponownie wykorzystane).iOS-Aktualizacja informacji UITableViewCell bez ponownego ładowania wiersza?

Jeśli chcesz zaktualizować etykietę bez dzwonienia pod numer reloadData lub reloadRowsAtIndexPaths, w jaki sposób możesz to zrobić?

Dla tych, którzy się zastanawiają - nie chcę wywoływać żadnej z metod reload..., ponieważ nie ma potrzeby ponownego ładowania całej komórki dla każdej aktualizacji punktu procentowego na download_progress.

Jedyne rozwiązania Natknąłem są:

  • Dodawanie komórkę jako obserwator klucz-wartość dla file „s download_progress.

  • Dzwonienie pod numer cellForRowAtIndexPath... bezpośrednio w celu uzyskania etykiety i zmiany jej tekstu.

Jednak KVO w ogóle nie jest zabawa api do pracy - a nawet mniej, więc po dodaniu ponownego wykorzystania komórek do mieszanki. Dzwonienie pod numer cellForRowAtIndexPath bezpośrednio za każdym razem, gdy dodawany jest punkt procentowy, wydaje się jednak nieprzyzwoite.

Jakie są więc możliwe rozwiązania? Każda pomoc będzie doceniona.

Dzięki.

+0

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

+0

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

+0

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

Odpowiedz

2

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ę!

1

Utworzę niestandardową komórkę, którą domyślam się zrobić. Następnie chciałbym, aby komórka nasłuchiwała określonego powiadomienia, które opublikowałaby twoja metoda pobierania, a następnie zaktualizuje tam etykietę. Musisz określić sposób postępu pobierania, aby określić konkretną komórkę, być może za pomocą ciągu znaków lub czegoś, co byłoby unikalne, aby można było określić metodę postępów pobierania, więc metoda aktualizacji komórki mogła zapewnić, że notatka była przeznaczone do tego. Daj mi znać, jeśli chcesz, abym wyjaśnił mój proces myślowy w tej sprawie.

+0

Tak, mogę spróbować NSNotification z unikalnym identyfikatorem pliku jako nazwą. Gdzie w cyklu życia komórki myślałeś o dodaniu/usunięciu komórki jako obserwatora? Dodaj w "tableviewWillDisplayCell ..." i usuń w "tableviewDidEndDisplayingCell ..."? – Christian

+0

Nie zaszedłem tak daleko, ale twoja sugestia jest prawdopodobnie całkiem dobrym miejscem do zrobienia tego. –