2015-09-02 23 views
8

Ho una vista tabella che contiene un segnaposto mentre carica nelle immagini. Quando l'immagine viene caricata, chiamo reloadRowsAtIndexPaths:withRowAnimation:. A questo punto, la cella cambia altezza, in base alla dimensione dell'immagine. Quando ciò accade, voglio che l'offset del contenuto della vista tabella rimanga al suo posto e che le celle sottostanti siano spinte più in basso, come puoi immaginare.UITableView scorre verso l'alto quando si ricaricano le celle con le altezze delle celle modificabili

L'effetto che sto ottenendo invece è che la vista di scorrimento scorre verso l'alto. Non sono sicuro del perché questo sia, e non riesco a impedirlo. Inserendo beginUpdates() prima e endUpdates() dopo che la riga reloadRows non ha alcun effetto.

Sto usando estimatedRowHeight, come è necessario in quanto la mia vista tabella può potenzialmente contenere centinaia di file di altezze diverse. Sto anche implementando tableView:heightForRowAtIndexPath:.

EDIT: Ho creato un progetto dimostrativo per testarlo, e ammetto che non riesco a ottenere il progetto demo per riprodurre questo effetto. Continuerò a lavorarci.

+0

È possibile inserire il codice che si utilizza per ottenere l'offset del contenuto della tabella e l'impostazione in cui si desidera mantenere lo stato attivo della tabella? –

risposta

11

Sempre aggiornare l'interfaccia utente sul thread principale . Quindi, è sufficiente posizionare

[self.tableView reloadData]; 

all'interno di un filo conduttore:

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

È un problema con EstimateRowHeight.

Più l'Altezza Rota stimata differisce dall'altezza effettiva, più la tabella potrebbe saltare quando viene ricaricata, specialmente più in basso è stato fatto scorrere. Questo perché la dimensione stimata della tabella differisce radicalmente dalle sue dimensioni effettive, costringendo la tabella a regolare le dimensioni e l'offset del contenuto.

La soluzione più semplice consiste nell'utilizzare una stima veramente accurata. Se l'altezza per riga varia notevolmente, determinare l'altezza mediana di una riga e utilizzarla come stima.

+0

Nel mio test, ho provato con una stima molto piccola e una stima molto ampia, ma nessuno dei due ha avuto l'effetto di scorrere indesideratamente. – Andrew

+0

Questa è una buona risposta. Grazie. L'altezza stimata non dovrebbe essere un numero casuale, ma vicino a ciò che pensi che sarà l'altezza. – darwindeeds

+0

grazie, questa è stata la ragione per me. a male funziona così però ... – warly

6

ho avuto lo stesso problema e decidere che in questo modo: salvare altezze di cellule quando carichi e dare valore esatto in tableView:estimatedHeightForRowAtIndexPath:

// 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

Nel mio caso ho avuto 'self.tableView.estimatedRowHeight = 44;' in superclasse.Impostandolo a zero nella classe corrente, dove ho fissato altezze di riga risolto il problema. –

0

Stavo vedendo questo, e la correzione che ha funzionato per me era scegliere un'altezza di riga stimata che è la più piccola delle possibili righe. Inizialmente era stato impostato sull'altezza della riga più grande possibile quando avveniva lo scorrimento involontario. Sto solo usando la singola proprietà tableView.estimatedRowHeight, non il metodo delegate.

Problemi correlati