Ich bin der Meinung, dass dies ein häufiges Problem sein könnte, und habe mich gefragt, ob es eine gemeinsame Lösung dafür gibt.
Grundsätzlich hat mein UITableView dynamische Zellenhöhen für jede Zelle. Wenn ich nicht oben in UITableView bin und ich tableView.reloadData()
, wird das Scrollen nach oben nervös.
Ich glaube, dies liegt an der Tatsache, dass UITableView die Höhe für jede Zelle, die sichtbar wird, neu berechnet, da ich beim Scrollen Daten hochgeladen habe. Wie kann ich das abmildern oder wie lade ich Daten nur von einem bestimmten IndexPath bis zum Ende der UITableView neu?
Wenn ich es schaffe, ganz nach oben zu scrollen, kann ich wieder nach unten und dann nach oben scrollen, kein Problem, ohne zu springen. Dies liegt höchstwahrscheinlich daran, dass die UITableViewCell-Höhen bereits berechnet wurden.
quelle
reloadRowsAtIndexPaths
. Aber (2) was meinst du mit "nervös" und (3) hast du eine geschätzte Zeilenhöhe eingestellt? (Ich versuche nur herauszufinden, ob es eine bessere Lösung gibt, mit der Sie die Tabelle dynamisch aktualisieren können.)x
bis zur letzten Zeile in meiner TableView auszuführen. Da ich jedoch neue Zeilen einfüge, funktioniert dies nicht. Ich kann nicht wissen, wie das Ende meiner Tabellenansicht vor dem erneuten Laden aussehen wird die Daten.Antworten:
Um ein Springen zu verhindern, sollten Sie beim Laden die Höhe der Zellen speichern und den genauen Wert angeben in
tableView:estimatedHeightForRowAtIndexPath
:Schnell:
Ziel c:
quelle
cellHeightsDictionary
:cellHeightsDictionary = [NSMutableDictionary dictionary];
estimatedHeightForRowAtIndexPath:
Gibt einen doppelten Wert zurück, kann einen*** Assertion failure in -[UISectionRowData refreshWithSection:tableView:tableViewRowData:]
Fehler verursachen. Um esreturn floorf(height.floatValue);
stattdessen zu beheben .Swift 3-Version der akzeptierten Antwort.
quelle
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
, dies erledigt alle Höhenberechnungen, die ich brauche.UITableViewDelegate
, meine Klasse zu erweitern. Die Anpassung an dieses Protokoll ist erforderlich, da es die oben gezeigtewillDisplay
Funktion enthält. Ich hoffe, ich kann jemandem den gleichen Kampf ersparen.Der Sprung ist wegen einer schlechten geschätzten Höhe. Je mehr sich die geschätzte Zeilenhöhe von der tatsächlichen Höhe unterscheidet, desto mehr kann die Tabelle springen, wenn sie neu geladen wird, insbesondere je weiter nach unten gescrollt wurde. Dies liegt daran, dass sich die geschätzte Größe der Tabelle radikal von der tatsächlichen Größe unterscheidet und die Tabelle gezwungen ist, ihre Inhaltsgröße und ihren Versatz anzupassen. Die geschätzte Höhe sollte also kein zufälliger Wert sein, sondern in der Nähe dessen, was Sie denken, dass die Höhe sein wird. Ich habe auch erfahren, wann ich festgelegt habe,
UITableViewAutomaticDimension
ob Ihre Zellen dann vom gleichen Typ sindWenn Sie verschiedene Zellen in verschiedenen Abschnitten haben, dann denke ich, ist der bessere Ort
quelle
tableView(_:estimatedHeightForHeaderInSection:)
@Igor Antwort funktioniert in diesem Fall gut,
Swift-4
Code davon.in folgenden Methoden von
UITableViewDelegate
quelle
Ich habe alle oben genannten Problemumgehungen ausprobiert, aber nichts hat funktioniert.
Nachdem Sie Stunden damit verbracht hatten, alle möglichen Frustrationen durchzugehen, fanden Sie einen Weg, dies zu beheben. Diese Lösung ist ein Lebensretter! Lief wie am Schnürchen!
Swift 4
Ich habe es als Erweiterung hinzugefügt, damit der Code sauberer aussieht und nicht jedes Mal, wenn ich neu laden möchte, alle diese Zeilen geschrieben werden.
schließlich ..
ODER Sie könnten diese Zeile tatsächlich zu Ihrer
UITableViewCell
awakeFromNib()
Methode hinzufügenund normal machen
reloadData()
quelle
reloadWithoutAnimation
aber wo ist derreload
Teil?tableView.reloadData()
zuerst anrufen und danntableView.reloadWithoutAnimation()
funktioniert es immer noch.Ich benutze mehr Möglichkeiten, um das Problem zu beheben:
Für View Controller:
als Erweiterung für UITableView
Das Ergebnis ist
quelle
Ich bin heute darauf gestoßen und habe Folgendes beobachtet:
cellForRowAtIndexPath
hilft nicht.Das Update war eigentlich ziemlich einfach:
Überschreiben Sie
estimatedHeightForRowAtIndexPath
und stellen Sie sicher, dass die richtigen Werte zurückgegeben werden.Damit hat alles seltsame Zittern und Herumspringen in meinen UITableViews aufgehört.
HINWEIS: Ich kenne die Größe meiner Zellen. Es gibt nur zwei mögliche Werte. Wenn Ihre Zellen wirklich eine variable Größe haben, möchten Sie möglicherweise die
cell.bounds.size.height
von zwischenspeicherntableView:willDisplayCell:forRowAtIndexPath:
quelle
Sie können tatsächlich nur bestimmte Zeilen neu laden, indem Sie
reloadRowsAtIndexPaths
Folgendes verwenden:Im Allgemeinen können Sie aber auch Änderungen der Tabellenzellenhöhe wie folgt animieren:
quelle
Hier ist eine etwas kürzere Version:
quelle
Überschreiben der geschätzten HeightForRowAtIndexPath-Methode mit einem hohen Wert, z. B. 300f
Dies sollte das Problem beheben :)
quelle
Es gibt einen Fehler, von dem ich glaube, dass er in iOS11 eingeführt wurde.
In
reload
diesem FallcontentOffSet
wird die tableView unerwartet geändert. In der TatcontentOffset
sollte sich nach einem Neuladen nicht ändern. Es kann aufgrund von Fehlkalkulationen von passierenUITableViewAutomaticDimension
Sie müssen Ihre speichern
contentOffSet
und nach dem erneuten Laden auf Ihren gespeicherten Wert zurücksetzen.Wie benutzt du es?
Diese Antwort wurde von hier abgeleitet
quelle
Dieser hat in Swift4 für mich gearbeitet:
quelle
Keine dieser Lösungen hat bei mir funktioniert. Folgendes habe ich mit Swift 4 & Xcode 10.1 gemacht ...
Deklarieren Sie in viewDidLoad () die dynamische Zeilenhöhe der Tabelle und erstellen Sie korrekte Einschränkungen in Zellen ...
Registrieren Sie auch in viewDidLoad () alle Ihre tableView-Zellennibs in tableview wie folgt:
Geben Sie in tableView heightForRowAt die Höhe zurück, die der Höhe jeder Zelle bei indexPath.row ... entspricht.
Geben Sie nun eine geschätzte Zeilenhöhe für jede Zelle in tableView EstimatedHeightForRowAt an. Sei genau wie du kannst ...
Das sollte funktionieren...
Ich musste contentOffset beim Aufrufen von tableView.reloadData () nicht speichern und festlegen.
quelle
Ich habe 2 verschiedene Zellenhöhen.
Nachdem ich schätzungsweise HeightForRowAt hinzugefügt hatte , gab es kein Springen mehr.
quelle
Versuchen Sie anzurufen,
cell.layoutSubviews()
bevor Sie die Zelle zurückgebenfunc cellForRowAtIndexPath(_ indexPath: NSIndexPath) -> UITableViewCell?
. Es ist ein Fehler in iOS8 bekannt.quelle
Sie können Folgendes in verwenden
ViewDidLoad()
quelle
Ich hatte dieses Sprungverhalten und konnte es zunächst durch Festlegen der genauen geschätzten Kopfhöhe abmildern (da ich nur eine mögliche Kopfzeilensicht hatte). Die Sprünge begannen dann jedoch speziell innerhalb der Kopfzeilen und wirkten sich nicht mehr auf die gesamte Tabelle aus.
Nach den Antworten hier hatte ich den Hinweis, dass es sich um Animationen handelt, und stellte fest, dass sich die Tabellenansicht in einer Stapelansicht befand, und manchmal riefen wir
stackView.layoutIfNeeded()
in einem Animationsblock auf. Meine endgültige Lösung bestand darin, sicherzustellen, dass dieser Aufruf nur dann erfolgt, wenn "wirklich" benötigt wird, da das Layout "falls erforderlich" in diesem Kontext visuelles Verhalten aufweist, selbst wenn "nicht benötigt".quelle
Ich hatte das gleiche Problem. Ich hatte Paginierung und erneutes Laden von Daten ohne Animation, aber es half der Schriftrolle nicht, das Springen zu verhindern. Ich habe eine andere Größe von IPhones, die Schriftrolle war auf dem iPhone 8 nicht nervös, aber auf dem iPhone 7 + war sie nervös
Ich habe folgende Änderungen an der viewDidLoad- Funktion vorgenommen:
und mein Problem gelöst. Ich hoffe es hilft dir auch.
quelle
Einer der Ansätze zur Lösung dieses Problems, den ich gefunden habe, ist
quelle
Eigentlich habe ich festgestellt, wenn Sie
reloadRows
ein Sprungproblem verursachen. Dann sollten Sie versuchen,reloadSections
wie folgt zu verwenden :quelle