2015-09-07 11 views
12

Mam widok tabeli z potencjałem dla każdej komórki, aby mieć własną wysokość, dlatego nie jest odpowiedni do używania rowHeight. Zamiast tego w tej chwili używam let indexSet = NSIndexSet(index: 10) i self.tableView.estimatedRowHeight = 75. Oznacza to, że wywołuje on funkcję sizeThatFits w komórce, aby określić jej wysokość. Wszystko działa dobrze.UITableView z dynamicznymi wysokościami komórek przeskakujących po przewinięciu się po przeładowaniu komórki

Problem polega na ponownym ładowaniu komórki wyświetlanej na ekranie. Przewijanie w dół, aby na przykład wyświetlić komórkę 10, a następnie przeładowanie komórki 10, działa dobrze. Ale kiedy zaczniesz przewijać w górę, mijając komórki, które już widziałeś, powracają one do oszacowanej wysokości dla każdej komórki, całkowicie pomijając sizeThatFits, i tak przeskakuje podczas przewijania. Byłoby niemożliwe, aby podać dokładny lub "wystarczająco dobry" szacowanyRowHeight, tak aby te skoki nie były zauważalne, ponieważ moje komórki będą mogły wyświetlać linię tekstu lub pełny obraz - duża różnica w rozmiar.

Mam ten efekt pokazany tutaj:

https://vid.me/edgW

Zrobiłem wiele różnych prób w tym, przy użyciu mieszanki heightForRowAtIndexPath, estimatedHeightForRowAtIndexPath .. itp .. Próbowałem różne kawałki porady dotyczące StackOverflow. Nic nie działa.

Mam załączeniu bardzo prosty przykładowy projekt, w którym można spróbować samemu:

https://www.dropbox.com/s/8f1rvkx9k23q6c1/tableviewtest.zip?dl=0

  1. uruchomić projekt.
  2. Przewiń, aby zobaczyć komórkę 10.
  3. Odczekaj 5 sekund, aż komórka się załaduje (stanie się fioletowa).
  4. Przewiń w górę.

Warto zauważyć - to nie ani, jeśli komórka nie jest widoczna po ponownym załadowaniu. Jeśli jest powyżej lub poniżej bieżącego punktu przewijania, wszystko działa zgodnie z oczekiwaniami.

+2

Nie wystarczy napisać projekt i prosić ludzi, aby dowiedzieć się problem. Zaktualizuj swoje pytanie za pomocą odpowiedniego kodu. – rmaddy

+0

Miałem podobny problem z "UICollectionView". oba są podobne, więc podobne podejście może w tym pomóc. opublikował [odpowiedź tutaj] (https://stackoverflow.com/a/45361410/6744473) – shoe

Odpowiedz

15

To zachowanie wydaje się być błędem, jeśli nie z innego powodu niż nie jest już odtwarzalne na iOS 9. Jestem pewien, że to nie jest dużo pocieszenia.

Problem wynika przede wszystkim z niedokładnego oszacowania, na przykład @NickCatib. Najlepsze, co możesz zrobić na iOS 8, jest poprawa oceny. Zalecaną przez wielu techniką jest zwiększenie wysokości pamięci podręcznej w willDisplayCell i użycie ich przy kolejnych połączeniach do estimatedRowHeightAtIndexPath.

Być może uda ci się złagodzić to zachowanie, nie robiąc nic, aby uzyskać UITableView odrzucenie jego pamięci podręcznych, na przykład przez zmodyfikowanie zawartości w komórce bezpośrednio przy użyciu cellForRowAtIndexPath zamiast ponownego ładowania, jeśli jest na ekranie. Jednak to nie pomoże, jeśli faktycznie musisz zmienić wysokość komórki.

Obawiam się powiedzieć, że błędu nie można łatwo naprawić w widoku tabeli, ponieważ nie masz kontroli nad układem. Błąd można łatwiej obrobić w podklasie UICollectionViewFlowLayout, zmieniając contentOffsetAdjustment podczas unieważniania, chociaż może to nie być takie łatwe.

+0

To jest poprawna odpowiedź: zwracanie właściwych wartości 'szacowanaRowHeightAtIndexPath:' całkowicie powoduje, że problem ten ustąpi. – MarcWan

+0

Bardzo cię kocham. To natychmiast rozwiązało mój problem. Jako ciekawy efekt uboczny, wysokość komórek pamięci podręcznej sprawia, że ​​przewijanie * naprawdę * szybko, więc naprawdę polecam buforowanie – Sirens

-1

Wystąpił ten sam problem, mój stół działa dobrze, aż tabela załaduje się ponownie. Więc znalazłem rozwiązanie, używaj tylko rowHeight nie szacowanej wysokości. Także, jeśli masz inną wysokość. Podaj pełny kod, więc dostarczę rozwiązanie. Mam komórkę, która przypomina stronę instagram. Przekazuję obliczoną wysokość w metodzie heightforrow, która działa dobrze. Ale szacowana wysokość nie działa dobrze w tej sytuacji. Jeśli użyjesz poniższego kodu, działa dobrze. Proszę spróbować.

self.tableView.rowHeight = 75 //it will be your dynamic height 
//self.tableView.estimatedRowHeight = 75 

Jeśli pomylisz się, aby obliczyć wysokość dla wiersza dla każdej komórki, po prostu dodaj próbkę i dostarczy rozwiązanie. Jeśli mogę Dzięki

0

Uh ... to jest trudny problem do załatwienia.

Rzućmy okiem na facebooka. Mieli ten sam problem ze swoją listą czasową, a skończyło się na tym, że robili to w pewnym widoku sieciowym.

Miałem podobny problem z jakimś harmonogramem, użyłem automatycznej wysokości wiersza i miałem ten problem. Pierwszą rzeczą, którą trzeba było rozwiązać, było ustawienie wartości estimatedHeight jak najbliżej średniej wysokości komórki.Jest to dość trudne, ponieważ możesz mieć tekst (wysokość 50) lub obrazy + tekst (wysokość 1500). Następną czynnością związaną z poprawą była implementacja estimatedHeight forIndexPath, która zasadniczo zwraca inną szacowaną wysokość dla różnych ścieżek indexPaths.

Potem było wiele innych rozwiązań, ale było to jak najbardziej zbliżone do zmiennych wysokości (ogromne różnice).

3

Miałem również ten problem i użyłem rozwiązania z SO, którego nie mogę teraz znaleźć. Jeśli to zrobię, dodam link. Oto rozwiązanie:

Problem polega na tym, że widok tabeli nie ma prawidłowej wartości szacunkowej dla wysokości rzędów. Aby to naprawić, buforuj wysokość początkowo w willDisplayCell i następnym razem użyj tej wysokości.

Kod

W viewDidLoad:

heightAtIndexPath = [NSMutableDictionary new]; 


- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath { 
    NSNumber *height = @(cell.frame.size.height); 
    [heightAtIndexPath setObject:height forKey:indexPath]; 
} 

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{ 
    return UITableViewAutomaticDimension; 
} 

- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath{ 
    if([heightAtIndexPath objectForKey:indexPath]) { 
     return [[heightAtIndexPath objectForKey:indexPath] floatValue]; 
    } else { 
     return UITableViewAutomaticDimension; 
    } 
} 
+1

Wreszcie! Dziękuję Ci!! –

+0

@ kam.voick nie ma za co! Nie uznaję jednak zasługi za odpowiedź, znalazłem ją gdzieś indziej na SO, ale nie mogę już znaleźć odnośnika do niej. Również witam w SO! –

Powiązane problemy