2015-09-02 4 views
8

Ich habe eine Tabellenansicht, die Platzhalter enthält, während sie in Bilder geladen wird. Wenn das Bild geladen ist, rufe ich reloadRowsAtIndexPaths:withRowAnimation:. An diesem Punkt ändert die Zelle die Höhe, basierend auf der Größe des Bildes. Wenn das passiert, möchte ich, dass der Inhaltsversatz der Tabellenansicht an Ort und Stelle bleibt und die darunter liegenden Zellen weiter nach unten geschoben werden, wie Sie sich vielleicht vorstellen können.UITableView scrollt nach oben, wenn Zellen mit wechselnden Zellenhöhen neu geladen werden

Der Effekt, den ich bekomme, ist, dass die Bildlaufansicht zurück nach oben scrollt. Ich bin nicht sicher, warum das so ist, und ich kann es anscheinend nicht verhindern. Putting beginUpdates() vor und endUpdates() nach der reloadRows Zeile hat keine Wirkung.

Ich verwende estimatedRowHeight, wie erforderlich ist, da meine Tabellenansicht potenziell Hunderte von Zeilen unterschiedlicher Höhe haben kann. Ich implementiere auch tableView:heightForRowAtIndexPath:.

EDIT: Ich habe ein Demo-Projekt eingerichtet, um dies zu testen, und zugegebenermaßen kann ich das Demo-Projekt nicht bekommen, diesen Effekt zu reproduzieren. Ich werde weiter daran arbeiten.

+0

Können Sie den Code posten, den Sie verwenden, um den Inhaltsoffset und die Einstellung des TableViews zu erhalten, wo der Tabellenansichtsfokus bleiben soll? –

Antwort

11

Immer aktualisieren Sie die Benutzeroberfläche auf dem Haupt-Thread. So platzieren Sie einfach

[self.tableView reloadData]; 

in einem Hauptthread:

dispatch_async(dispatch_get_main_queue(), ^{ 
    //UI Updating code here. 
    [self.tableView reloadData]; 
}); 
27

Es ist ein Problem mit der geschätztenRowHeight.

Je mehr die geschätzteRowHeight von der tatsächlichen Höhe abweicht, desto mehr springt die Tabelle beim erneuten Laden, besonders wenn sie weiter nach unten scrollt. Dies liegt daran, dass die geschätzte Größe der Tabelle sich radikal von der tatsächlichen Größe unterscheidet, sodass die Tabelle ihre Inhaltsgröße und ihren Offset anpassen muss.

Die einfachste Problemumgehung ist, eine wirklich genaue Schätzung zu verwenden. Wenn die Höhe pro Zeile stark variiert, bestimmen Sie die mittlere Höhe für eine Zeile und verwenden Sie diese als Schätzung.

+0

In meinem Test versuchte ich mit einer sehr kleinen Schätzung und einer sehr großen Schätzung, aber keiner hatte den Effekt des unerwünschten Scrollens. – Andrew

+0

Das ist eine ziemlich gute Antwort. Vielen Dank. Die geschätzte Höhe sollte keine Zufallszahl sein, sondern nahe an dem, von dem Sie denken, dass die Höhe sein wird. – darwindeeds

+0

danke, das war der Grund für mich. zu schlecht funktioniert es aber auch so ... – warly

6

ich hatte das gleiche Problem und entscheiden, es auf diese Weise: Höhen von Zellen speichern, wenn sie lädt und die genauen Wert in tableView:estimatedHeightForRowAtIndexPath geben:

// declare cellHeightsDictionary 
NSMutableDictionary *cellHeightsDictionary; 

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

// give exact height value 
- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath { 
    NSNumber *height = [cellHeightsDictionary objectForKey:indexPath]; 
    if (height) return height.doubleValue; 
    return UITableViewAutomaticDimension; 
} 
+0

In meinem Fall hatte ich 'self.tableView.estimatedRowHeight = 44;' in superclass.Wenn ich es in der aktuellen Klasse auf Null setze, wo ich feste Zeilenhöhen habe, habe ich das Problem behoben. –

0

Ich sah dies, und die Lösung, die für mich funktionierte, war, eine geschätzte Zeilenhöhe zu wählen, die die kleinste der möglichen Zeilen ist. Es war ursprünglich auf die größtmögliche Zeilenhöhe eingestellt worden, als das unbeabsichtigte Scrollen stattfand. Ich verwende nur die einzige tableView.estimatedRowHeight-Eigenschaft, nicht die Delegate-Methode.

Verwandte Themen