Pagination UITableView

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • Pagination UITableView

    Moin zusammen,

    ich bin gerade dabei mir eine Pagination zu basteln für mein TableView.

    Ich lade die Daten jetzt nach ,wenn die letzte Zeile erreicht ist mit "tableView-->willDisplay".

    Das funktioniert auch alles wunderbar. Nur wenn ich am Ende der Tabelle bin und die Daten nachgeladen werden verspringt meine Position ein paar Zeilen (2 oder 3) nach unten. Das heißt wenn man weiterscrollt nach unten verpasst man 2-3 Zeilen.

    Gibt es einen Befehl, damit die Position nicht verspringt? holdpositionbeimnachladen oder so :)

    Danke euch
  • Also grob gesagt:

    Ich habe ein Array mit meinen Daten. Beim nachladen erweitere ich das Array und führe dann tableView.reloadData() aus. Dies ist doch der korrekte Weg oder nicht?

    Wird bei jedem reload die komplete Tabelle neu gezeichnet? Das heißt wenn ich pro "Page" 10 Einträge habe und jemand scrollt bis zu 200 Einträge. Werden dann beim reload die kompleten 200 geladen oder nur die noch fehlenden? Oder sollte man hier anders an die Sache rangehen?

    Danke euch.
  • Ok. Verstehe ich noch nicht ganz.

    Prefetching läd Zellen schon mal vor je nach dem in welche Richtung man scrollt?

    Oder kann ich mir jetzt tableview.reloadData() dadurch sparen?

    Zur Zeit läuft es wie folgt:

    1. Array wird gefüllt mit Objekten
    2. tableView wird neu geladen mit tableView.reloadData()

    Wie würde es mit Prefetching aussehen?

    Weitere Frage:

    Ich lade 1 Bild und ein wenig Text in jede Zelle. Ist hier besser UICollectionView oder UITableView zu verwenden?

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von piepenschneider () aus folgendem Grund: neue frage

  • Ich glaube ich habe nur einen Denkfehler. Im Prinzip funktioniert es ja außer das er beim Nachladen an eine komische Position springt:

    Der Ablauf:

    1. Ich habe ein Array mit Objekten

    2. Objekt werden der TableView hinzufügt und die TableView wird neugeladen

    3. Scrollt der Nutzer ans Ende wird an das Array mit Objekten neue Objekte angefügt und TableView wird neugeladen

    Ist dieser Weg falsch?

    nsscreencast.com/episodes/315-tableview-prefetching dafür muss man irgendwie registiert sein
  • Kommt halt was du machen willst. Wenn du ein Array mit 1000 Objekten hast werden immer nur die Objekte aus dem Array geladen, die gerade sichtbar sind.

    Wenn du so und so alle Objekte im Array bereits geladen hast dann brauchst du auch keinen reload. Das macht der tableview

    Hast du aber so viele Objekte, dass auf einmal laden zu viel wäre dann das Prefetching etc.
  • @piepenschneider: Oder um es noch einmal auf den Punkt zu bringen ... wie auch von @AppleDeveloper geschrieben:
    • Wenn - wie Du oben schriebst - Deine Sorge dem "Zeichnen der Tabelle" gilt, Du die eigentlichen Tabellendaten aber schon vorliegen hast: Vergiß es, das händelt die UITableView und allokiert / reused nur neue Zellen bzw. ermittelt deren Inhalt, wenn diese in den sichtbaren Bereich scrollen. Ein explizites reloadData: ist hier kontraproduktiv.
    • Wenn Du aber sehr aufwändige Methoden hast, den Zellinhalt bereitzustellen, kannst Du mit UITableViewDataSourcePrefetching Daten für Zellinhalte im voraus ermitteln und so den o. g. Mechanismus perfomanter gestalten

    Apple schrieb:

    You use a prefetch data source object in conjunction with your table view’s data source to begin loading data for cells before the tableView:cellForRowAtIndexPath: data source method is called.
    Somit hast Du zwei zusätzliche (prefetch)Datasource-Methoden, die Dich darüber informieren, für welchen IndexPath Du Daten bereitstellen solltest ... und tableView:cellForRowAtIndexPath: muss pfiffig genug sein, mit den unterschiedlichen Situationen des asynchronen Ladens umzugehen...

    Mattes
    Diese Seite bleibt aus technischen Gründen unbedruckt.
  • Du musst die Datasource implementieren. Dein Datenmodell muss das entsprechende TableView Datasource-Protokoll implementiert haben.

    Via Protokoll „fragt“ der TableView ua und eigentlich nur einmal, wieviele Datensätze es gibt, sonst weiß der ja nicht mal, wie weit runter gescrollt werden kann. Du gibst zwar diese Auskunft, änderst „Deine Meinung“ jedoch laufend, indem du dem Array Datensätze hinzufügst und dann dem TV mitteilst, er soll nochmal von vorne anfangen.

    Gestalte Dein Datenmodell so, dass die Anzahl der DS von Anfang an feststeht.
  • Ok :D

    Danke erstmal für die vielen Antworten. Weiß garnicht was ich ohne euch machen würde.

    Ich möchte dem User Daten anzeigen abhängig von seinem Standort. Die Daten sind quasi unendlich. Ähnlich wie der FB Newsfeed. Ich habe immer ein Bild und ein paar labels.

    Ob der Nutzer natürlich 1000 Einträge scrollt ist natürlich unwarscheinlich.

    Sollte ich eurer Meinung nach jetzt z. B. 100 Einträge laden und wenn er bei 100 angekommen ist die nächsten 100. Wird ja eh selten passieren.

    Oder mit prefetching immer 10 Einträge?

    Persönlich würde ich das von der Geschwindigkeit ausmachen. Leider habe ich da keine Erfahrung welches die bessere Variante ist.
  • Da es hier um eine iOS App geht, sollte ja nur eine mobile Internetverbindung zur Verfügung stehen. Da kann man sich natürlich auch mal schnell im Edge-Land befinden und somit ist die Up-/Download-Geschwindigkeit begrenzt. :(

    Bei Edge wären dann sicherlich 10 Einträge das Maximum. Mit vollem LTE könnten es dann sicherlich auch 20 oder mehr sein. Generell scheinen mir kleinere Werte jedoch sinnvoller, da neben der Geschwindigkeit ggf. auch das Datenvolumen begrenzt ist.

    Wie Du auch schon angemerkt hast, wird der Nutzer sich wohl eher selten 100 oder gar 1000 Einträge anschauen.

    Wie viele Einträge passen denn gleichzeitig auf dem Bildschirm?

    Vielleicht bietet sich da ein Block von je 3 Bildschirmen an.
  • Ich würde die Tabelle auf eine realistische Maximal-Anzahl von Zeilen begrenzen („Wie weit blättet ein Benutzer wirklich, wann sind weitere Ergebisse irrelevant?“). Dann die Zellen per Prefetch füllen, wenn die Datenbeschaffung dauert (dazu hast Du Dich m. E. bisher nicht geäußert).

    Unendlich“ macht aus meiner Sicht überhaupt keinen Sinn...

    Mattes
    Diese Seite bleibt aus technischen Gründen unbedruckt.
  • Die Daten sind über die API recht schnell da. Habe die Sache aufm Handy getestet und für 100 Zeilen benötigt es ca 2-3 Sekunden, dann ist alles fertig geladen und man kann gemütlich scrollen. Denke ich werde es erstmal so belassen das ich 100 Zeilen lade und wenn jemand so viel langeweile hat bekommt er nach den 100 Zeillen wieder 100.

    Weitere Frage:

    Wenn ich 100 Zeilen lade mit jeweils einem Bild pro Zeile ... läd die App dann alle 100 Bilder runter oder nur für die Zeile die gerade sichtbar ist? Wenn er 100 Bilder läd wäre das ja nicht so vorteilhaft.
  • piepenschneider schrieb:

    Wenn ich 100 Zeilen lade mit jeweils einem Bild pro Zeile ... läd die App dann alle 100 Bilder runter oder nur für die Zeile die gerade sichtbar ist? Wenn er 100 Bilder läd wäre das ja nicht so vorteilhaft.

    Meinst Du mit "laden" jetzt laden vom Server oder laden in den Speicher. Beides hängt von Deinem Code ab. iOS bzw. der UITableView fordert jedoch nur Zellen per Delegate Methoden an, die angezeigt werden. In Deinem Fall dann wohl erst mal nur 2-3 Zellen. Sobald dann gescrollt wird und eine weitere Zelle in den sichtbaren Bereich gelangt, wird über die Delegate Methoden eine Zelle angefordert. Dies kann dann eine komplett neue oder recycelte Zelle sein die aus dem sichtbaren Bereich verschwunden ist.

    Wenn Du jetzt UITableViewDataSourcePrefetching verwendest, dann könnte ich mir vorstellen, dass in Deinem Fall tableView:prefetchRowsAtIndexPaths: evtl. für die ersten 4 Zeilen aufgerufen wird. Dies lässt sich ja schnell per NSLog oder Breakpoints testen/ermitteln. ;)