2009-08-25 16 views
6

Ho trovato alcuni post simili al mio problema, ma non proprio uguali.righe duplicate in tableview su uitableviewcell

Nella mia app l'utente può navigare tra diverse visualizzazioni di prova per visualizzare il risultato desiderato. Quando un utente va avanti, quindi indietro, poi avanti, ecc., È evidente che le righe vengono ridisegnate/riscritte e il testo diventa più audace e più audace.

Ho trovato che in alcuni dei post questo può riguardare il modo in cui sto creando le righe, utilizzando un uable nel metodo cellforrowatindexpath.

C'è qualcosa che devo fare in modo che le righe non vengano ripopolate/ridisegnate ogni volta che un utente va avanti e indietro tra le tabelle? Devo aggiungere qualcosa al codice qui sotto o aggiungere qualcosa al metodo viewwillappear (attualmente c'è un 'reloaddata' nel viewwillappear per la tabella ma non sembra essere di aiuto)?

Ecco il mio codice:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
static NSString *CellIdentifier = @"Cell"; 

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 
if (cell == nil) 
{ 
    cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease]; 
} 
    cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; 

    UILabel *label = [[[UILabel alloc] init] autorelease]; 
    label.font = [UIFont fontWithName:@"Arial-BoldMT" size:20]; 
    label.frame = CGRectMake(10.0f, 10.0f, 220.0f, 22.0f); 
    label.textColor = [UIColor blackColor]; 
    label.backgroundColor = [UIColor clearColor]; 
    label.opaque = NO; 
    label.text = [mapareaArray objectAtIndex:indexPath.row]; 
    [cell.contentView addSubview:label]; 

    CustomCellBackgroundView *bgView = [[CustomCellBackgroundView alloc] initWithFrame:CGRectZero]; 
    bgView.borderColor = [UIColor clearColor]; 
    bgView.fillColor = [UIColor whiteColor]; 
    bgView.position = CustomCellBackgroundViewPositionSingle; 
    cell.backgroundView = bgView; 
    return cell; 
} 

risposta

11

Il problema che si è dovuta a questa linea:

[cell.contentView addSubview:label]; 

Si sta aggiungendo una visualizzazione secondaria alla cella della tabella che si tratti di una nuova cella o no . Se è una vecchia cella (deselezionata dal pool riutilizzabile), allora aggiungerai un'altra sottocategoria alla cella.

Invece, dovresti taggare l'UILabel, e quindi individuarlo con il tag per modificare il contenuto di tale UILabel. Aggiungere (e impostare tutti i suoi attributi) e contrassegnare l'UILabel all'interno del se (cella == nil) Blocco:

if(cell == nil) { 
    // alloc and init the cell view... 

    UILabel *label = [[[UILabel alloc] init] autorelease]; 
    label.tag = kMyTag; // define kMyTag in your header file using #define 
    // and other label customizations 
    [cell.contentView addSubview:label]; // addSubview here and only here 
    ... 
} 

quindi individuare con:

UILabel *label = (UILabel *)[cell.contentView viewWithTag: kMyTag]; 
label.text = [mapareaArray objectAtIndex:indexPath.row]; 

E non c'è bisogno di aggiungere nuovamente è una sottoview al di fuori del blocco if (cell == nil). La sottoview è già lì (ed è per questo che riutilizzare le viste delle celle è molto più efficiente, se lo fai correttamente, cioè;).

+0

Grazie mille per questo. Grande aiuto Un'ultima domanda al riguardo - Non ho uno sfondo di programmazione quindi non sono sicuro di cosa intendi usando #define nel file di intestazione. Qual è la sintassi per fare questo? L'ho visto prima e ho tentato di inserire "#define kMyTag" nell'intestazione, ma questo non funziona ...Suppongo che tu abbia bisogno di definire kMyTag su un valore ma non sono sicuro di quale sarebbe la sintassi per farlo. Puoi aiutare? – SKayser

1

file h Il 'definire' è messo dopo le dichiarazioni #import in cima alla file di intestazione, ed è stato messo come 0, perché non so come altro definirlo:

#define kMyTag 0 

. m file Ho aggiornato questa sezione come da vostri commenti, ma a) la tabella non è popolata, b) quando l'utente ha navigato alla vista successiva e torna a questa vista fallisce con un "selettore non riconosciuto inviato all'istanza" e c) ho dovuto inserire le due "celle di restituzione"; voci o cade sopra. Penso di avere le cose nell'ordine sbagliato e forse non ho inizializzato correttamente le cose ????

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
static NSString *CellIdentifier = @"Cell"; 
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 

if (cell == nil) 
    { 
     cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease]; 
     cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; 
     cell.selectionStyle = UITableViewCellSelectionStyleNone; 

     UILabel *label = [[[UILabel alloc] init] autorelease]; 
     label.tag = kMyTag; // define kMyTag in your header file using #define 
     label.font = [UIFont fontWithName:@"Arial-BoldMT" size:20]; 
     label.frame = CGRectMake(10.0f, 10.0f, 220.0f, 22.0f); 
     label.textColor = [UIColor blackColor]; 
     label.backgroundColor = [UIColor clearColor]; 
     label.opaque = NO; 

     CustomCellBackgroundView *bgView = [[CustomCellBackgroundView alloc] initWithFrame:CGRectZero]; 
     bgView.borderColor = [UIColor clearColor]; 
     bgView.fillColor = [UIColor whiteColor]; 
     bgView.position = CustomCellBackgroundViewPositionSingle; 
     cell.backgroundView = bgView; 

     [cell.contentView addSubview:label]; // addSubview here and only here 
     return cell; 
    } 
UILabel *label = (UILabel *)[cell.contentView viewWithTag: kMyTag]; 
label.text = [mapareaArray objectAtIndex:indexPath.row]; 
return cell; 
} 
+0

Non sono sicuro se dovresti usare 0 per il valore di kMyTag. Prova a partire da 1, poiché 0 potrebbe essere l'impostazione predefinita per tutto. Dopo questa modifica, rimuovi la cella di ritorno all'interno del blocco if. – tchen

+0

Grazie ancora! Funziona ora! Apprezzo il tuo tempo! – SKayser

0

Si dovrebbe creare una sottoclasse per UITableViewCell per quella specifica cella, quindi applicare la logica per vedere se è necessario aggiungere la visualizzazione secondaria a se stesso ogni volta. Inoltre, usa la funzione PrepForReuse di UITableviewcell e rimuovi eventuali sottoview in quel periodo prima di applicare la logica di se vuoi aggiungere un UILabel alla tua cella.