2009-08-29 13 views
87

Mam uitableview, który ładuje dość duże obrazy w każdej komórce, a wysokości komórek różnią się w zależności od rozmiaru obrazu. Wydajność przewijania jest przyzwoita, ale czasami może być nierówna.Sztuczki poprawiające wydajność przewijania iPhone UITableView?

znalazłem te wskazówki znalazłem na blogu FieryRobot:

glassy-scrolling-with-uitableview

more-glassy-scrolling-with-uitableview

Czy ktoś ma jakieś wskazówki dotyczące poprawy wydajności przewijania UITableView?

+0

Jeśli chcesz buforować wysokości komórek (które mogą być kosztowne w obliczaniu i są często używane), podałem przykład. Używaj tego tylko, jeśli jest odpowiedni w twojej aplikacji. http://stackoverflow.com/questions/1371223/how-do-i-cache-something-for-a-tableview/10992748#10992748 –

Odpowiedz

151
  1. Cache wysokość wierszy (widok tabeli mogą wystąpić to często)
  2. Tworzenie najmniej niedawno używane pamięci podręcznej dla obrazów wykorzystywanych w tabeli (i unieważnia wszystkie nieaktywne wpisy, gdy otrzyma ostrzeżenie pamięć)
  3. Draw wszystko w UITableViewCell „s drawRect: jeśli to możliwe subviews uniknąć za wszelką cenę (lub jeśli wymagają standardową funkcjonalność dostępności, widok zawartości na drawRect:)
  4. Dokonać UITableViewCell” warstwa nieprzezroczysta (sa s mi idzie na widok zawartości, jeśli masz jeden)
  5. Użyj funkcji reusableCellIdentifier zalecane przez UITableView examples/dokumentacji
  6. Unikaj gradienty/skomplikowanych efektów graficznych, które nie są wstępnie upieczone w UIImage s
+4

Dodatkowo, pobrane obrazy powinny zostać przeskalowane do rozmiaru obrazuView przed wyświetleniem w komórce! –

+3

Chciałbym dodać do tej odpowiedzi jedno moje doświadczenie z ostatnich kilku lat - posiadanie przezroczystych komórek prawdopodobnie nigdy nie jest przyczyną złego przewijania wydajności. Mamy aplikację z BARDZO skomplikowanymi komórkami (20+ subviews) i wszystko jest przezroczyste, aby pokazać tło. Przy odpowiednich optymalizacjach przezroczystość nie ma znaczenia nawet w przypadku 3GS. Właściwie to, co zwolniło najbardziej, było ładowanie nib, zanim było wystarczająco dużo komórek do usunięcia z widoku tabeli. Jeśli korzystasz z subviews, po prostu upewnij się, że masz wydajne hierarchie i nie musisz używać drawRect. – Accatyyc

+0

@Accatyyc, wydaje się, że mam ten sam problem. Występuje małe opóźnienie, gdy nie ma wystarczającej ilości komórek do usunięcia, gdy 3-4 komórki są odrywane, a następnie przewijanie jest płynne.Czy istnieje jakiś sposób wstępnego ładowania komórek, więc istnieją komórki do usunięcia i nie załadować plików NIB podczas przewijania? – Tiois

40
  1. Jeśli instacji UITableViewCell, nie używać NIB, napisać go w kodzie zamiast. Jest o wiele szybszy niż ładowanie plików Nib.
  2. Jeśli używasz obrazów, upewnij jesteś buforowanie je więc nie mieć załadować z pliku ponad raz dla każdego (jeśli masz pamięć - możesz być zaskoczony, jak wiele zdjęć przestrzennych).
  3. Możliwe jest użycie wielu elementów nieprzezroczystych jako . Podobnie, spróbuj i nie używaj obrazów o przezroczystości.
+0

Dwa neg głosów? Ooookay ... –

+3

Nie martw się ... to były trolle. świetna odpowiedź! – Steav

+0

dzięki za buforowanie obrazu wskazówka – pepsi

33

Twórca Tweetie napisał o tym obszernie i ma trochę kodu, który pokazuje, jak to zostało zrobione dla tej aplikacji. Zasadniczo, on/ona opowiada się za jednym niestandardowym widokiem na komórkę tabeli i rysuje go ręcznie (zamiast subskrybowania za pomocą Konstruktora interfejsu, pośród innych opcji).

fast-scrolling-in-tweetie-with-uitableview

Ponadto, Apple uaktualnił swój własny kod przykładowy Tableview w swoich tutoriali TableViewSuite (być może w odpowiedzi na to?)

TableViewSuite

+1

To jest niesamowite rozwiązanie. Ciekawi mnie tylko, jak dodać UIButton do cellView? Czy jest narysowany w metodzie drawRect? –

+1

@beno, Twój link wydaje się zepsuty (pierwszy) jakakolwiek szansa na umieszczenie naszych rąk na oryginalnym artykule? – apouche

+2

Oryginalny artykuł można przeczytać tutaj: http://web.archive.org/web/20100922230053/http://blog.atebits.com/2008/12/fast-scrolling-in-tweetie-with-uitableview/ – jverdi

1

# 1 wydajność zabójca dla UITableView przewijanie jest rysunek cienie na dowolnej warstwie widoku komórki, więc jeśli przewijanie ma znaczenie, to nie rób cienia, chyba że w zasadzie nie spowalnia głównego wątku.

myślałem, że to trzeba powiedzieć, ponieważ żadna z przyjętych odpowiedzi nie zawierała wzmianek o cieniach i warstwach. : +)

+3

jeśli problemami są cienie dodaj to dwie linie kodu i wszystko działa idealnie self.layer.shouldRasterize = YES; self.layer.rasterizationScale = UIScreen.mainScreen.scale; –

0

Każdy problem z wydajnością przewijania UITableView można rozwiązać za pomocą technik opisanych już w innych odpowiedziach. Jednak wiele razy powolna wydajność jest spowodowana przez coś z natury błędne lub powtarzalne.

Fakt, że UITableView ponownie wykorzystuje komórki, oraz fakt, że każda komórka może potrzebować własnego obrazu - razem sprawia, że ​​rozwiązanie jest skomplikowane. Od tego, jak jest rozwiązywany w ogólny sposób, tutaj podsumowuję rzeczy, którymi należy się zająć:

  1. Załaduj dane do źródła danych - z REST/bazy danych. Ten krok powinien zostać wykonany w tle, ostatecznie przy użyciu metody dispatch_async wraz z kolejką GCD.
  2. Tworzenie i zainicjować odpowiednie obiekty modelu danych i umieszczenie ich wewnątrz tablicy
  3. [tableView reloaddata]
  4. Wewnątrz cellForRowAtIndexPath zawierać kod, który zestaw danych (tekst) z prawidłowym model danych obiektu tablicy.
  5. Teraz obrazy mogą mieć również postać adresu URL, więc ten krok może być trochę dziwaczny z powodu ponownego użycia komórki przez widok tabeli. Chodzi o to, aby ponownie załadować obraz z pamięci podręcznej urządzenia/adresu URL za pomocą kolejki asynchronicznej, a następnie ustawić go tak, aby poprawiał obraz komórki. (Niezależnie od tego, jaka jest własność obrazu komórki).

Aby uniknąć problemów, zapoznaj się z tym samouczkiem na temat widoku wewnątrz tabeli lazy loading of images.

Powiązane problemy