Tricks zur Verbesserung der Bildlaufleistung von iPhone UITableView?

89

Ich habe eine geeignete Ansicht, die ziemlich große Bilder in jede Zelle lädt und deren Zellenhöhen je nach Größe des Bildes variieren. Die Bildlaufleistung ist anständig, kann aber manchmal ruckartig sein.

Ich habe diese Tipps im FieryRobot-Blog gefunden:

Glas-Scrollen-mit-geeigneter Ansicht

mehr glasiges Scrollen mit passender Ansicht

Hat jemand Tipps zur Verbesserung der Scroll-Leistung von uitableview?

Jona
quelle
Wenn Sie die Zellenhöhen zwischenspeichern müssen (deren Berechnung teuer sein kann und auch häufig verwendet wird), habe ich ein Beispiel gegeben. Verwenden Sie diese Option nur, wenn sie für Ihre Anwendung geeignet ist. stackoverflow.com/questions/1371223/…
Paul de Lange

Antworten:

156
  1. Zwischenspeichern Sie die Höhe der Zeilen (die Tabellenansicht kann dies häufig anfordern).
  2. Erstellen Sie einen zuletzt verwendeten Cache für die in der Tabelle verwendeten Bilder (und machen Sie alle inaktiven Einträge ungültig, wenn Sie eine Speicherwarnung erhalten).
  3. Zeichnen Sie alles in die UITableViewCell's, drawRect:wenn möglich, vermeiden Sie Unteransichten um jeden Preis (oder wenn Sie die Standardfunktionalität für Barrierefreiheit benötigen, die Inhaltsansichten drawRect:)
  4. Machen Sie UITableViewCelldie Ebene Ihrer Ebene undurchsichtig (dasselbe gilt für die Inhaltsansicht, falls Sie eine haben)
  5. Verwenden Sie die in den UITableViewBeispielen / Dokumentationen empfohlene Funktion reusableCellIdentifier
  6. Vermeiden Sie Farbverläufe / komplizierte grafische Effekte, die nicht in UIImages vorgebacken sind
rpetrich
quelle
5
Außerdem sollten heruntergeladene Bilder auf die Größe der imageView verkleinert werden, bevor sie in der Zelle angezeigt werden!
Zoltán Matók
4
Ich möchte dieser Antwort eine meiner Erfahrungen aus den letzten Jahren hinzufügen - transparente Zellen sind wahrscheinlich nie die Ursache für eine schlechte Bildlaufleistung. Wir haben eine App mit SEHR komplizierten Zellen (über 20 Unteransichten) und alles ist transparent, um den Hintergrund anzuzeigen. Bei richtigen Optimierungen macht die Transparenz auch bei einem 3GS keinen Unterschied. Tatsächlich verlangsamte sich das Laden der Feder am meisten, bevor genügend Zellen vorhanden waren, um sich aus der Tabellenansicht zu entfernen. Wenn Sie Unteransichten verwenden, stellen Sie einfach sicher, dass Sie über effiziente Hierarchien verfügen, und Sie müssen drawRect nicht verwenden.
Accatyyc
@Accatyyc, es scheint, dass ich das gleiche Problem habe. Es gibt eine kleine Verzögerung, wenn nicht genügend Zellen zum Ausreihen vorhanden sind. Wenn 3-4 Zellen aus der Warteschlange entfernt werden, ist das Scrollen reibungslos. Gibt es eine Möglichkeit, Zellen vorab zu laden, damit beim Scrollen Zellen aus der Warteschlange entfernt und keine NIB-Dateien geladen werden können?
Tiois
@Tiois Sicher gibt es. Sie müssen die alte Methode zum Entfernen von Zellen verwenden (registrieren Sie keine Klassen / Schreibfedern, sondern erstellen Sie sie, wenn dequeueCellWithIdentifier: null zurückgibt). Auf diese Weise können Sie eine Reihe von Zellen erstellen, bevor Ihre Tabellenansicht überhaupt vorhanden ist, z. B. 20 davon zuvor. Anstatt neue in cellForRowAtIndexPath: zu erstellen, ziehen Sie sie zuerst aus Ihrem eigenen Cache, bis sie leer sind.
Accatyyc
Ich verwende UICollectionView und habe das gleiche Problem. In meiner benutzerdefinierten Cell Nib-Datei. Ich verwende mehrere Unteransichten, einschließlich UIwebView und UIImageView in vertikalem UIstackView. Wenn ich in meiner Liste scrolle, brauchen wiederverwendete Zellen viel Zeit, um ihre Größe anzupassen, und das Scrollen sieht sehr ruckelig aus.
Mansuu ....
40
  1. Wenn Sie eine Unterklasse verwenden UITableViewCell, verwenden Sie keine Schreibfeder, sondern schreiben Sie sie stattdessen in Code. Es ist viel schneller als das Laden von Nib-Dateien.
  2. Wenn Sie Bilder verwenden, stellen Sie sicher, dass Sie sie zwischenspeichern, damit Sie nicht mehr als einmal aus der Datei laden müssen (wenn Sie über den Speicher verfügen, wären Sie überrascht, wie viel Speicherplatz Bilder beanspruchen).
  3. Machen Sie so viele Elemente wie möglich undurchsichtig. Versuchen Sie auch nicht, Bilder mit Transparenz zu verwenden.
Zottiger Frosch
quelle
3
Mach dir keine Sorgen ... das waren Trolle. gute Antwort!
Steav
79
Die Abstimmungen waren wahrscheinlich darauf zurückzuführen, dass "Vermeiden von Federn" ein schlechter Rat für die Verbesserung der Leistung ist. Wenn Sie Zellen wiederverwenden, werden die Zellen beim Scrollen überhaupt nicht aus Schreibfedern rekonstruiert.
Steven Fisher
6
Nibs sind gleich schnell oder etwas schneller, basierend auf Cocoa with Love-Forschungen. cocoawithlove.com/2010/03/…
MaxGabriel
@Steven Fisher, der Nib verwendet, ist möglicherweise langsamer, wenn Tabellenzellen zuweisen und freigeben, z. B. beim schnellen Scrollen.
Sound Blaster
3
NIBs Unter Verwendung kann langsamer sein , wenn die Zelle wird aufgebaut . Wenn Sie das Zellrecycling verwenden, sind nur genügend Zellen zugeordnet, um den Bildschirm auszufüllen. sagen wir, vielleicht höchstens 10. Beim Scrollen werden keine Zellen erstellt. Sie werden nur wiederverwendet , nicht freigegeben und neu zugewiesen. Und natürlich gibt es keine Kosten für die Freigabe. Also nein, das ist nicht richtig.
Steven Fisher
34

Der Entwickler hinter Tweetie hat ausführlich darüber geschrieben und verfügt über Code, der zeigt, wie es für diese App gemacht wurde. Grundsätzlich befürwortet er / sie eine benutzerdefinierte Ansicht pro Tabellenzelle und zeichnet sie manuell (anstatt sie unter anderem mit Interface Builder zu unterzeichnen).

schnelles Scrollen-in-Tweetie-mit-geeigneter Ansicht

Außerdem hat Apple in seinen TableViewSuite-Tutorials einen eigenen Beispielcode für TableView aktualisiert (möglicherweise als Antwort darauf?).

TableViewSuite

Beno
quelle
1
Dies ist eine großartige Lösung. Ich bin nur neugierig, wie ich einen UIButton in die cellView einfügen soll. Wird es in der drawRect-Methode gezeichnet?
Sukitha Udugamasooriya
1
@beno, Ihr Link scheint kaputt zu sein (der erste). Gibt es eine Chance, den Originalartikel in die Hand zu nehmen?
Apouche
3
Der Originalartikel kann hier gelesen werden: web.archive.org/web/20100922230053/http://blog.atebits.com/2008/…
jverdi
Link zum Webarchiv hinzugefügt, da die Originalversion nicht existiert
Ralph Willgoss
1

Der Leistungskiller Nr. 1 für das Scrollen mit UITableView ist das Zeichnen von Schatten auf einer beliebigen Ebene der Zellenansicht. Wenn also die Leistung des Bildlaufs wichtig ist, machen Sie keine Schatten, es sei denn, dies verlangsamt Ihren Haupt-Thread im Grunde nicht.

dachte, dies müsse gesagt werden, da in keiner der akzeptierten Antworten Schatten und Schichten erwähnt wurden. : +)

JackyJohnson
quelle
6
Wenn die Probleme die Schatten sind, fügen Sie diese beiden Codezeilen hinzu und alles funktioniert perfekt self.layer.shouldRasterize = YES; self.layer.rasterizationScale = UIScreen.mainScreen.scale;
Pedro Romão
0

Jedes Problem mit der UITableViewBildlaufleistung kann mithilfe von Techniken gelöst werden, die bereits in anderen Antworten beschrieben wurden. Eine oftmals träge Leistung wird jedoch durch etwas verursacht, das von Natur aus fehlerhaft oder sich wiederholend ist.

Die Tatsache, dass UITableViewdie Zellen wiederverwendet werden und dass jede Zelle möglicherweise ein eigenes Bild benötigt - zusammen macht die Lösung etwas komplexer. Ausgehend davon, wie es allgemein gelöst wird, fasse ich hier Dinge zusammen, die erledigt werden sollten:

  1. Laden Sie Daten in die Datenquelle - aus REST / Datenbank. Dieser Schritt sollte im Hintergrund ausgeführt werden und schließlich dispatch_async zusammen mit der GCD-Warteschlange verwenden.
  2. Erstellen und initialisieren Sie relevante Datenmodellobjekte und fügen Sie sie in ein Array ein
  3. [tableView reloaddata]
  4. Fügen Sie cellForRowAtIndexPathCode hinzu, der Daten (Text) aus dem richtigen Datenmodellobjekt des Arrays festlegt.
  5. Jetzt haben Bilder möglicherweise auch die Form einer URL, sodass dieser Schritt aufgrund der Wiederverwendung von Zellen in der Tabellenansicht möglicherweise etwas eigenartig ist. Das Herzstück der Tatsache ist, das Image mithilfe der asynchronen Warteschlange erneut aus dem Geräte-Cache / der URL zu laden und dann auf cell.image zu korrigieren (unabhängig von Ihrer Cell-Image-Eigenschaft).

Um Probleme zu vermeiden, lesen Sie dieses Tutorial zum verzögerten Laden von Bildern in der Tabellenansicht.

Nirav Bhatt
quelle