2011-11-17 9 views
21

Mam tricky problem dotyczący aktualizacji mój Tableview, i uzyskać różne wyniki przy użyciu różnych metod aktualizowania go, pozwól mi wyjaśnić:Tableview reloadData vs. beginUpdates & endUpdates

Sytuacja 1: używam [tbl reloadData]; gdzie tbl to mój TableView, aby zaktualizować TableView - działa zgodnie z przeznaczeniem.

Sytuacja 2: używam:

[tbl beginUpdates]; 
[tbl reloadRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationRight]; 
[tbl endUpdates]; 

Gdzie jest moja Tableview tbl i indexPaths jest tablicą zawierającą wszystkie indexPaths obecne w Tableview. Teraz tablica jest w porządku, zawiera wszystkie poprawne pola indexPaths (podwójne i potrójne zaznaczone), ale z jakiegoś powodu - to nie działa zgodnie z przeznaczeniem.

Teraz zdaję sobie sprawę, że jest to problem XY (gdzie pytam o Y, ale mój problem jest naprawdę X, ponieważ myślę, że rozwiązanie Y rozwiąże X) i to tylko dlatego, że uważam, że to trochę skomplikowane wyjaśnienie X (konsekwencja powyższy problem) w łatwy sposób, więc wolałbym od tego powstrzymać się, jeśli to możliwe.

Tak więc, na moje pytanie: Czy istnieje różnica między dwoma sposobami aktualizowania TableView (oprócz oczywiście animacji) lub czy powinienem podejrzewać, że problem leży gdzieś indziej?

EDIT: Dobra, postaram się wyjaśnić, jakie objawy są:

W cellForRowAtIndexPath -method dodać przycisk do każdej komórki z przypisanym tagiem który jest równy komórki indexPath rzędu jak takie:

btn.tag = indexPath.row; 

powodem robię to więc mogę zidentyfikować każdy przycisk jak wszyscy nazywają tę samą funkcję:

- (void)btnPressed:(id)sender 

Kiedy następnie aktualizuję komórki - ponieważ niektóre wartości w komórkach się zmieniły - Sytuacja 1 sprawia, że ​​wszystko działa poprawnie, Sytuacja 2 jednak - miesza tagi, aby następnym razem nacisnąć jeden z przycisków, nie mają już poprawne tagi.

Mieszanie wydaje mi się losowe, ale losowość przebiega różnie, w zależności od tego, który przycisk komórki naciska się najpierw. Mam nadzieję, że to wyjaśni mój problem.

+1

"Otrzymuję różne wyniki", "to nie działa zgodnie z przeznaczeniem." W jaki sposób? – TigerCoding

+0

Cóż, każda komórka otrzymuje przycisk przy tworzeniu, z tagiem, gdzie 'tag przycisku = wiersz ścieżki indeksu'. W sytuacji 1 przycisk otrzymuje poprawną etykietę, w sytuacji 2 - nie. –

Odpowiedz

19

Z UITableView dokumentacji

beginUpdates
rozpocząć serię metody wymaga, że ​​wkładka, usuwać lub wybrać wiersze i fragmenty odbiornika.

Oznacza to, że nie powinieneś tego używać, chyba że wstawiasz, usuwasz lub wybierasz. Nie robisz żadnej z nich.

Należy również zakończyć beginUpdates z endUpdates, a nie reloadData.Dokumentacja:

Ta grupa metod musi zakończyć się wywołaniem metody endUpdates.

+1

Ach, tak, '' reloadData'-bit był literówką w moim poście - moim złym. –

+0

Dobra, to oznacza różnicę między reloadData i beginUpdates/endUpdates, ale tak naprawdę nie mogę powiedzieć, jak różnica ta powinna wpłynąć na mój wynik w sposób, w jaki to robi. Zdaję sobie sprawę, że opisując konsekwencje byłem nieco niejasny, za kilka minut zaktualizuję moje oryginalne pytanie. –

+0

Spróbuj upuścić 'beginUpdates' oraz' endUpdates'. Nie należą one do 'updateRowsAtIndexPaths'. – Mundi

3

Pierwsza różnica między reloadData i reloadRowsAtIndexPaths jest to, że istnieją 2 UITableViewCell obiektów dedykowanych simulteaneosuly dla tego samego indexPath robiąc reloadRowsAtIndexPaths (bo tableview „wtapia” się w nowej komórce). Czasem nie jest to przewidziane przez kod w cellForRowAtIndexPath. Zaskoczenie wynika z faktu, że nawet jeśli komórka została już przydzielona dla konkretnego identyfikatora komórki, widok tabeli nie zwróci tej komórki w dequeueReusableCellWithIdentifier podczas wywoływania reloadRowsAtIndexPaths, zamiast tego zwraca zero . W sprzeczności reloadData ponownie wykorzystuje komórki, które już przydzielono.

The 2nd Różnica polega na tym, że endUpdates po reloadRowsAtIndexPaths bezpośrednio wywołuje cellForRowAtIndexPath (jeśli ustawisz tam breakpoint, endUpdates widoczny jest ślad stosu), natomiast reloadData harmonogramów rozmowy do cellForRowAtIndexPath w późniejszym czasie (nie widoczne w ślad stosu) .

Jednak trzeba by napisać nieco więcej kodu, aby dać nam wgląd w to, co tam robisz. Zasadniczo indexPaths nowych komórek są identyczne do starych również z reloadRowsAtIndexPaths, o ile nie usuniesz ani nie wstawisz wierszy.

+0

Dziękuję za odpowiedź Leo. Minęło już kilka lat i nie pamiętam, co stało się z tym projektem, ale wątpię, czy kiedykolwiek go rozwiązałem, mam nadzieję, że to Q i odpowiedzi udzielone przez ciebie i @Mundi pomogą komuś z podobnymi problemami. –

0

Zadzwoń do tej metody, jeśli chcesz, aby kolejne operacje wstawiania, usuwania i selekcji (na przykład cellForRowAtIndexPath: i indexPathsForVisibleRows) były animowane jednocześnie.

Myślę, że tego właśnie chcesz. beginUpdates & endUpdates może zmienić widok UItable z animacją.

Powiązane problemy