2011-11-17 15 views
21

Ho un problema difficile per quanto riguarda l'aggiornamento il mio TableView, ottengo risultati diversi con metodi diversi di aggiornarlo, mi spiego:TableView reloadData vs. beginUpdates & endUpdates

Situazione 1: Io uso [tbl reloadData]; dove tbl è il mio TableView, per aggiornare TableView - funziona come previsto.

Situazione 2 che utilizzo:

[tbl beginUpdates]; 
[tbl reloadRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationRight]; 
[tbl endUpdates]; 

Dove tbl è la mia TableView, e indexPaths è un array contenente tutti i indexPaths presenti nel TableView. Ora la matrice è a posto, contiene tutti i indexPath corretti (double e triple checked) ma per qualche ragione - questo non funziona come previsto.

Ora mi rendo conto che questo è un problema XY (dove chiedo Y ma il mio problema è davvero X perché penso che risolvere Y risolverà X) e questo è solo perché sento che è un po 'complicato spiegare X (la conseguenza di detto sopra il problema) in un modo semplice, quindi preferirei astenermi da ciò se possibile.

Quindi, fino alla mia domanda: C'è una differenza tra i due modi di aggiornare il TableView (a parte il bit dell'animazione ovviamente) o dovrei sospettare che il problema si trovi altrove?

EDIT: Va bene, cercherò di spiegare quali sono i sintomi:

Nel cellForRowAtIndexPath -Metodo aggiungo un pulsante per ogni cella con un tag assegnato che è uguale alla riga indexPath della cella , come ad esempio:

btn.tag = indexPath.row; 

il motivo per cui faccio questo è così posso identificare ogni tasto come tutti chiamano la stessa funzione:

- (void)btnPressed:(id)sender 

Quando aggiorno le celle - perché alcuni valori nelle celle sono cambiati - La situazione 1 rende tutto a posto, tuttavia la situazione 2 - mescola i tag in modo che la prossima volta che uno dei pulsanti viene premuto, non abbiano più il tag corretti.

Il mix-up sembra casuale per me, ma la randomizzazione si verifica in modo diverso a seconda del pulsante delle celle che premo per primo. Spero che questo chiarisca il mio problema.

+1

"ottengo risultati diversi", "questo non funziona come previsto". In quale modo? – TigerCoding

+0

Bene, ogni cella riceve un pulsante al momento della creazione, con un tag, dove "il tag button = la riga del percorso dell'indice". Nella Situazione 1 il pulsante ottiene il tag corretto, in Situazione 2 - non lo fa. –

risposta

19

Dalle UITableView documentazione

beginUpdates
iniziare una serie di metodo di chiamate che inserire, eliminare o selezionare le righe e le sezioni del ricevitore.

Ciò significa che non si dovrebbe usare questo a meno che non si stia inserendo, eliminando o selezionando. Non stai facendo nessuno di questi.

Inoltre, è necessario terminare beginUpdates con endUpdates, non reloadData.Documentazione:

Questo gruppo di metodi deve concludersi con una chiamata di endUpdates.

+1

Ah, sì il bit 'reloadData' era un refuso nel mio post - il mio male. –

+0

Ok, allora si conclude la differenza tra reloadData e beginUpdates/endUpdates, ma non riesco davvero a capire in che modo questa differenza dovrebbe influenzare il mio risultato nel modo in cui lo fa. Mi rendo conto di essere stato un po 'vago nel descrivere le conseguenze, aggiornerò la mia domanda iniziale tra un paio di minuti. –

+0

Prova a eliminare 'beginUpdates' e' endUpdates'. Non appartengono a 'updateRowsAtIndexPaths'. – Mundi

3

La prima differenza tra reloadData e reloadRowsAtIndexPaths è che ci sono 2 UITableViewCell oggetti allocati simulteaneosuly per lo stesso indexPath quando si fa reloadRowsAtIndexPaths (perché tableView 'fonde' nella nuova cella). Questo a volte non è previsto dal codice in cellForRowAtIndexPath. La sorpresa deriva dal fatto che anche se una cella era già allocata per un particolare identificatore di cella, la vista tabella non restituisce questa cella in dequeueReusableCellWithIdentifier quando chiama reloadRowsAtIndexPaths, invece restituisce nil . In contraddizione, reloadData riutilizza le celle già allocate.

La seconda differenza è che endUpdates dopo reloadRowsAtIndexPaths chiama direttamente cellForRowAtIndexPath (se si imposta un punto di interruzione lì, endUpdates è visibile nella traccia dello stack), mentre reloadData orari le chiamate a cellForRowAtIndexPath in un secondo momento (non visibili nella traccia dello stack) .

Tuttavia, è necessario inserire un po 'più di codice per darci un'idea di ciò che si sta facendo lì. In linea di principio i IndexPath delle nuove celle sono identici a quelli vecchi anche con reloadRowsAtIndexPaths a condizione che non vengano eliminate o inserite righe.

+0

Grazie per la risposta Leo. Sono passati alcuni anni e non ricordo cosa sia successo a questo progetto, ma dubito che l'abbia mai risolto, spero che questa Q e le risposte fornite da te e @Mundi aiutino qualcun altro con problemi simili. –

0

Chiamare questo metodo se si desidera che le successive operazioni di inserimento, eliminazione e selezione (ad esempio, cellForRowAtIndexPath: e indexPathsForVisibleRows) vengano animate contemporaneamente.

Penso che questo sia quello che vuoi. beginUpdates & endUpdates può modificare l'UItableview con l'animazione.

Problemi correlati