2010-02-23 8 views
24

Mam widok UITableview, który ładuję z asynchronizacją danych, więc widok tabeli może pojawić się bez danych.
Zmęczony metoda ReloadData, ale widok tabeli pozostaje pusty, dopóki nie przewiń tabeli, nagle pojawiają się dane.
To samo dzieje się, gdy ładuję widok tabeli jako widok szczegółowy i przełączanie między pozycjami, dane elementów poprzedzających pojawiają się jako pierwsze i jak tylko przewijam w widoku tabeli, wyświetlają poprawne dane.
Domyślam się, że metoda ReloadData działa dobrze, ale muszę przerysować tabelę w jakiś sposób, wszelkie sugestie, jak rozwiązać ten problem?Przerysuj UITableView po zaktualizowaniu danych async

/Jimmy

+0

Zwykle metoda reloadData odświeża widok tableview. Czy możesz umieścić próbkę swojego kodu TableViewController? –

Odpowiedz

53

Mówiłeś jesteś wypełniania zawartości asynchronicznie ale czy wywołać reloadData w kontekście wątku głównego? (A nie za pośrednictwem gwintu, który zapełnia się zawartość)

celu C

[yourUITableView performSelectorOnMainThread:@selector(reloadData) 
            withObject:nil 
           waitUntilDone:NO]; 

Swift

dispatch_async(dispatch_get_main_queue(), { self.tableView.reloadData() }) 

MonoTouch

InvokeOnMainThread(() => this.TableView.ReloadData()); 
+7

Dzięki, że rozwiązany =) rozwiązaniem dla monotouch jest: InvokeOnMainThread (() => this.TableView.ReloadData()); –

+0

@yonel Mam ten sam problem co JimmyEngtröm i naprawdę miałem nadzieję, że to, co powiedziałeś, zrobi to, ale niestety nadal mam ten problem. Nie mogę znaleźć sposobu na odświeżenie UITableView po aktualizacji podstawowych tablic danych, których używa. –

+0

@ MasonG.Zhwiti: ustaw punkt przerwania w swojej metodzie numberOfResInSections w źródle danych tabeli i sprawdź, czy wchodzi w niego po reloadData. Następnie sprawdź liczbę wierszy, które tu zwrócisz, jeśli nie ma wartości 0, to wywoła ona cellForRowAtIndex. – yonel

2

Przypuszczam, że nie został załadowany ponownie.

Podczas przewijania komórek do siebie na ekranie, a następnie ...

tableView: cellForRowAtIndexPath:

... zostanie wywołana. Zostanie więc ponownie załadowany.

Domyślna zmienna UITableView nie została zweryfikowana.

Jeśli używasz UITableView jako widoku głównego, możesz spróbować tego.

[self.view reloadData];

lub

[self.tableView reloadData];

4

Yonels odpowiedź jest idealny, gdy widok jest aktualnie widoczne dla użytkownika (np: użytkownik naciśnie przycisk przeładowania która zapełnia swój UITableView).

Jednakże, jeśli dane są ładowane asynchronicznie a UITableView nie jest widoczny podczas aktualizacji (np .: Dodajesz Dane do swojego UITableView w innym Widoku, a UITableView jest wyświetlany później przez userinput), po prostu przesłonię metodę UITableViewController 's.

- (void)viewWillAppear:(BOOL)animated{ 
[super viewWillAppear:animated]; 
[self.tableView reloadData]; 
} 

Pozytywnym efektem jest to, że UITableView przeładowuje tylko jest to dane raz, gdy użytkownik faktycznie chce, aby ją zobaczyć, a nie kiedy nowe elementy są dodawane.

2

Miałem podobny problem dzisiaj (Storyboard w iOS 7.0). Używam tabeli Zobacz wewnątrz UIViewController. Gdy widok został załadowany wszystko działało dobrze; wszyscy delegaci zostali wezwani.Jednak ; Kiedy podstawowy sourceSource (w moim przypadku Array) został zmodyfikowany; widoczne wiersze tabeli nie były aktualizowane. Zostały zaktualizowane; tylko wtedy, gdy przewijałem widok tabeli.

Próbowałem wszystkiego; wywoływanie reloadData w głównym wątku, wywoływanie przeładowania w ViewWillAppear; nic nie działało.

Problem, który znalazłem; było to, że nie nawiązałem połączenia w storybooku; dla widoku tabeli z referencyjnym Outletem. DataSource i delegate zostały ustawione. Nie sądziłem, że to może być problem; ponieważ wszystko działało dobrze na pierwszym wyjściu.

Mam nadzieję, że komuś pomógł.Miałem straszny czas, aby to znaleźć.

0

Po pewnym naiwnym skopiowaniu rozwiązania Yonela i nazwaniu go dobrym, zdałem sobie sprawę, że wywołanie performSelectorOnMainThread:withObject:waitUntilDone: naprawiło symptom, ale nie problem. Większy problem polega na tym, że robisz aktualizacje UI, gdy wciąż jesteś w kontekście wątku asynchronicznego lub tła.

To właśnie mój kod wyglądało:

dispatch_queue_t queue = dispatch_queue_create("com.kyleclegg.myqueue", NULL); 
dispatch_async(queue, ^{ 

    // Make API call 
    // Retrieve data, parse JSON, update local properties 
    // Make a call to reload table data 

}); 

Kiedy powinno to wyglądać tak:

dispatch_queue_t queue = dispatch_queue_create("com.kyleclegg.myqueue", NULL); 
dispatch_async(queue, ^{ 

    // Make API call 
    // Retrieve data, parse JSON, update local properties 

    dispatch_async(dispatch_get_main_queue(), ^{ 
    // Now make the call to reload data and make any other UI updates 
    [self.tableView reloadData] 
    }); 

}); 

Jeśli tylko rzeczą, którą musisz zrobić to zadzwonić [self.tableView reloadData] to chyba dobrze, aby użyj performSelectorOnMainThread:withObject:waitUntilDone:, ponieważ osiąga ten sam cel, ale powinieneś także rozpoznać, co dzieje się na dużym obrazie. Także, jeśli robisz więcej pracy z UI niż tylko ponowne ładowanie tabeli, to cały ten kod powinien również iść do głównej kolejki.

Odniesienie: A concise example korzystania z GCD i zarządzania tłem a głównym wątkiem.

Powiązane problemy