2012-01-21 20 views
5

Sto riscontrando qualche problema con il metodo reloadData di UITableView. Ho scoperto che chiama solo cellForRowAtIndexPath se ci sono nuove celle da aggiungere o da portare via.Forza UITableView per chiamare cellForRowAtIndexPath: per tutte le celle

Esempio: ho cinque celle, ciascuna contenente cinque stringhe. Se aggiungo una nuova cella e chiamo reloadData, la tabella viene aggiornata e io la vedo. Tuttavia, se vado in una delle cinque celle, aggiungo una nuova stringa, quindi ritorno e chiamo reloadData, nessuno dei metodi delegati della vista tabella viene chiamato.

La mia domanda: è possibile forzare la vista tabella per ricaricare completamente i dati in tutte le sue celle visibili?

risposta

8

Ho trovato il problema: avevo il codice di personalizzazione della cella nel blocco if(cell == nil), quindi, poiché le celle venivano riciclate, non venivano modificate. Prendendo il mio codice di personalizzazione da quel blocco risolto il problema.

+0

Hai risparmiato le mie ore di sforzi. Grazie! Non avrei immaginato questo stupido errore :) – Pruthvid

+0

Contento che la mia soluzione possa aiutare qualcun altro! –

0

Bene, la vista tabella chiamerà solo cellForRowAtIndexPath sulle celle visibili ma se si chiama reloadData lo farà, quindi c'è qualcos'altro che sta succedendo qui e non sono sicuro di cosa sia.

+0

In questo caso, tutte le celle sono visibili. So che l'origine dati (in questo esempio, NSUserDefaults) è in fase di aggiornamento, quindi non sono esattamente sicuro del motivo per cui solo le nuove celle vengono aggiornate. –

+0

Hai rintracciato le chiamate a 'cellForRowAtIndexPath' per dimostrare che non viene chiamato o stai semplicemente non vedendo un cambiamento visivo? Se 'cellForRowAtIndexPath' non viene chiamato ... Non so cosa sta succedendo. A quel punto, farei un passo indietro e tracciare le chiamate a 'numberOfRowsInSection'. In ogni caso, posso dire che 'cellForRowAtIndexPath' _should_ essere chiamato per ogni cella visibile quando si esegue' reloadData'. – smparkes

+0

NSLogs dice che quando aggiungo una nuova riga, tutto viene aggiornato; la mia ipotesi iniziale era sbagliata. Quando si chiama reloadData al ritorno alla visualizzazione tabella da un altro controller di visualizzazione, non viene chiamato nulla. –

0

Anche se la tua vista tabella ha 50 righe, ci saranno solo le celle che possono essere visibili contemporaneamente. Questa è l'intera storia dietro il riutilizzatore. Quindi forzare "tutte le celle" non esiste. Se viene visualizzata una nuova cella, i dati vengono caricati in modo dinamico.

L'unico modo per modificare una cella è modificare i dati forniti dal metodo dataSource cellForRowAtIndexPath.

+1

Ho scritto un misspoke nella mia domanda; Ora l'ho aggiornato. –

+0

E se provi 'reloadRowsAtIndexPaths: withRowAnimation:' Solo per controllare ... Non lasciare che questa sia la soluzione. – Jodocus

+0

Anche questo non funziona; non ha alcun effetto. –

0

Non estrarre il codice dal blocco if (cell == nil). Invece, crea un identificatore rappresentativo per la cella che stai creando; prova e assicurati che tutti i contenuti della cella siano indicati nell'identificatore. Ad esempio, se si visualizzano 3 numeri, assicurarsi di avere quei tre numeri nell'identificatore in un modo univoco che farebbe riferimento solo a una cella con tale contenuto.

Supponiamo di avere tre proprietà NSArray nella classe, array1, array2 e array3 che hanno valori int racchiusi all'interno degli oggetti NSNumber. Si desidera utilizzare questi NSArrays per riempire un UITableView, questo è quello che farei:

- (UITableViewCell *)tableView:(UITableView *)tableView 
        cellForRowAtIndexPath:(NSIndexPath *)indexPath { 
    NSString *identifier = [NSString stringWithFormat:@"%@-%@-%@", 
          [[array1 objectAtIndex:indexPath.row] intValue], 
          [[array2 objectAtIndex:indexPath.row] intValue], 
          [[array3 objectAtIndex:indexPath.row] intValue]]; 
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier]; 

    if (cell == nil) { 
     cell = [[[UITableViewCell alloc] 
            initWithStyle:UITableViewCellStyleDefault 
            reuseIdentifier:identifier] autorelease]; 

     //Build your cell here. 
    } 

    return cell; 
} 
1

ho trovato che il ricaricamento sezioni ricarica dei dati più facilmente. Se v'è solo una sezione si può provare:

[self.tableView reloadSections:[NSIndexSet indexSetWithIndex:0] withRowAnimation:UITableViewRowAnimationNone];

1

si può provare questo

[tableView reloadData]; 

o

[tableView deleteRowsAtIndexPaths:[NSMutableArray arrayWithObjects:indexPath, nil] withRowAnimation:UITableViewRowAnimationFade]; 

mettere questo in commitEditingStyle metodo.

Problemi correlati