2012-03-20 15 views
11

Sto usando un UITableView e sto notando che le celle nella mia tableview diventano progressivamente più audaci mentre faccio scorrere, sovrascrive il contenuto e voglio fermarlo ma non riesco a vedere dove sto andando male.Come fermare cella UITableView è sovrascrivere il contenuto?

Sul mio UITableView, per qualche motivo quando faccio scorrere il contenuto della vista tabella si incasina con la UILabel creata manualmente.

Ho bisogno di un UILabel manuale perché ho bisogno di avere celle personalizzate in seguito.

Mentre scorro su e giù, le etichette diventano progressivamente più audaci e più audaci; si sovrappongono sempre e a volte colpiscono anche le righe più in basso (anche prima che siano nella vista).

Se continuo a farlo, il contenuto della cella diventa incomprensibile.

Questo succede solo se il backgroundColor non è impostato come clearColor.

Ho tentato [cellLabel setClearsContextBeforeDrawing:YES]; e [self.tableView setClearsContextBeforeDrawing:YES]; senza alcun effetto.

Se utilizzo cell.textLabel.text, il problema sembra scomparire.

Segue un esempio di immagine.

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

     UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 
     if (cell == nil) { 
      cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease]; 
     } 

     // Configure the cell... 
     //[self configureCell:cell atIndexPath:indexPath]; 


     NSString *txt = @"Product"; 


     //cell.textLabel.text = txt; 
     cell.selectionStyle = UITableViewCellSelectionStyleNone; 

     UIView *cellView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 200, cell.frame.size.height)]; 

     UILabel *cellLabel = [[UILabel alloc] initWithFrame:CGRectMake(20, 10, 120, 35)]; 
     [cellLabel setText:txt]; 
     [cellLabel setFont:[UIFont boldSystemFontOfSize:12]]; 
     [cellLabel setBackgroundColor:[UIColor clearColor]]; 

     [cellView addSubview:cellLabel]; 
     [cellLabel release]; 
     [cell.contentView addSubview:cellView]; 
     [cellView release]; 


     return cell; 
    } 


Image follows; 


![image of uitableview][1] 


    [1]: http://i.stack.imgur.com/5lNy6.png 


// Edit to include context 

I am using a dictionary to display the contents of the UITableViewCells. 

I have attempted to do the following; 

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

     UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 
     if (cell == nil) { 
      cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease]; 

      [self configureCell:cell atIndexPath:indexPath]; 
     } // end if 


     // Configure the cell... 
     // 
     // Moved to inside the cell==nil   

     return cell; 
    } 

-(void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath 
{ 

    // Get the txt from the Dictionary/Plist... *removed due verboseness* 

    UILabel *cellLabel = [[UILabel alloc] initWithFrame:CGRectMake(20, 10, 120, 35)]; 
    [cellLabel setText:txt]; 
    [cellLabel setFont:[UIFont boldSystemFontOfSize:12]]; 
    [cellLabel setBackgroundColor:[UIColor clearColor]]; 

    [cell.contentView addSubview:cellLabel]; 
    [cellLabel release]; 
} 

questo, anche se risolve il problema di sovrascrittura - causa un problema - rende etichette compaiono ripetutamente in luoghi totalmente casuali - il seguente è solo un esempio, altri campi e le etichette anche ripetono.

vedi foto sotto;

repeating labels in uitableview

+0

possibile duplicato di [UITableView celle ripetute su scroll] (http: // stackoverflow.it/questions/6844156/uitableview-repeat-cells-on-scroll) –

risposta

17
// cell reuse 
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 

si restituito il cellulare già stato utilizzato, ha già una visualizzazione secondaria UILabel e si sta aggiungendo un altro su di esso. Mettere le subviews aggiungendo alla sezione

if (cell == nil) { //cell initialization 

e modificare i subviews come necessario dopo l'inizializzazione delle cellule, è possibile accedervi per tag, per esempio.

+0

Ho provato a configurare UILabels sotto la parte 'cell == nil', mentre questo non consente la sovrascrittura, causa un altro problema - mette dati in aree casuali nella vista tabella. Il mio vero codice completo usa un dizionario (plist), e la cella inizia a inserire la stessa voce in posti casuali in tutta la tabella, aggiornerò la mia domanda per coprire questo problema. – zardon

+2

@zardon gli UILabels che vengono aggiunti una volta non vengono cancellati quando si riutilizza la cella con 'dequeueReusableCellWithIdentifier', è responsabilità dell'utente aggiornare il contenuto delle visualizzazioni secondarie o ripristinare l'aspetto predefinito (come setText: @" "per UILabel). In caso contrario, sarà possibile visualizzare sottoquadri precedentemente configurati nelle celle riutilizzate (nel caso in cui si modifichi il contenuto della cella in modo condizionale). –

+0

Ho provato ad aggiornare il contesto, ma non penso che funzioni. Proverò a creare init di UILabels all'interno della cella == nil e cercherò di accedervi per tag e vedere se questo aiuta. Potrei anche cercare tutorial su questo perché non ho mai visto prima questo approccio. – zardon

0

Provare a non inserire UIView * cellView sulla cella UITableViewCell *. UITableViewCell è una sottoclasse di un UIView in modo che tu possa aggiungere le subviews se lo desideri. Tuttavia UITableViewCell ha già un'etichetta all'interno.

Basta usare [cell.textLabel setText:txt].

+0

Non posso usare textLabel per questa attività perché ho bisogno di combinare un textlabel, un gadget di input e anche altri gadget. – zardon

-1

La risposta di A-Live è stata la soluzione migliore.

Ho trovato https://developer.apple.com/library/ios/#documentation/UserExperience/Conceptual/TableView_iPhone/TableViewCells/TableViewCells.html per dare un esempio molto più ampio.

Tuttavia, nei miei esperimenti sono stato in grado di configurare UITableViewCells che non ha sovrascritto e non ha inserito valori di cella in posizioni casuali.

Il codice che ho usato è al di sotto, si potrebbe fare con tiyding, ma sembra funzionare per il momento;

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 
if (cell == nil) { 
    cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease]; 

    cell.selectionStyle = UITableViewCellSelectionStyleNone; 

    UILabel *cellLabel = [[UILabel alloc] initWithFrame:CGRectMake(20, 10, 120, 35)]; 
    [cellLabel setFont:[UIFont boldSystemFontOfSize:12]]; 
    [cellLabel setBackgroundColor:[UIColor clearColor]]; 
    [cellLabel setTag:1]; 
    [cell.contentView addSubview:cellLabel]; 
    [cellLabel release]; 




    // TextInput setup  
    CGRect cellTextFrame = CGRectMake(200, 12, 65, 30); 


    UITextField *txtInputField = [[UITextField alloc] initWithFrame:cellTextFrame]; 
    [txtInputField setTag:2]; 
    [txtInputField setDelegate:self]; 
    [txtInputField setClearButtonMode:UITextFieldViewModeWhileEditing]; 
    [txtInputField setContentVerticalAlignment:UIControlContentVerticalAlignmentCenter]; 
    [txtInputField setFont:[UIFont systemFontOfSize:12]]; 
    [txtInputField setReturnKeyType:UIReturnKeyDone]; 
    [txtInputField setTextAlignment:UITextAlignmentLeft]; 
    [txtInputField setKeyboardAppearance:UIKeyboardAppearanceDefault]; 
    [txtInputField setKeyboardType:UIKeyboardTypeNumbersAndPunctuation]; 
    [txtInputField setAutocorrectionType:UITextAutocorrectionTypeNo]; 
    [txtInputField setAutocapitalizationType:UITextAutocapitalizationTypeNone]; 
    txtInputField.clearButtonMode = UITextFieldViewModeWhileEditing; 
    [txtInputField setBorderStyle:UITextBorderStyleRoundedRect]; 
    txtInputField.textColor = [UIColor colorWithRed:56.0f/255.0f green:84.0f/255.0f blue:135.0f/255.0f alpha:1.0f]; 
    //[txtInputField addTarget:self action:@selector(textFieldFinished:) forControlEvents:UIControlEventEditingDidEndOnExit];  

    [cell.contentView addSubview:txtInputField]; 
    [txtInputField release]; 

} // end if 


// Configure the cell... 
// 
//[self configureCell:cell atIndexPath:indexPath]; 


UILabel *label = (UILabel *)[cell viewWithTag:1]; 
[label setText:txt]; 

UITextField *txtField = (UITextField *) [cell viewWithTag:2]; 
[txtField setText:txtText]; 
[txtField setPlaceholder:txtPlaceholder]; 



return cell; 
4
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ 

      UITableViewCell *cell = (UITableViewCell*)[self.YourTableName dequeueReusableCellWithIdentifier:nil];   
     if (cell == nil) { 
      cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:nil]; 
     } 


      return cell; 
     } 

uso ReusablecellIdentifier pari a zero in modo da farlo funzionare correttamente .....

+0

nice one grazie – Chlebta

+0

Questa è l'unica cosa che ha funzionato per me .. – durazno

+0

avevo provato xcode 7 ReusablecellIdentifier nil non funziona. mostra qualche problema di avvertimento non argomento cellee passato null. –

6

Si sta aggiungendo l'etichetta alla stessa cella riutilizzati ogni volta, è per questo che è sempre più audace. Quando si utilizza dequeueReusableCellWithIdentifier, si acquisisce una cella che è già stata visualizzata sullo schermo, che è la cosa corretta da fare, ma è già stata inserita un'etichetta. Poiché l'etichetta si troverà ogni volta nella stessa posizione rispetto alla cella, e lo stesso colore ecc. (L'unico elemento dinamico sarà il testo), è necessario impostare tutto solo una volta.

La soluzione preferita è creare una cella personalizzata con le proprietà desiderate. Quindi, in questo caso, è necessario creare

@interfacce MyCustomCell : UITableViewCell 
    @property (nonatomic) UILabel *cellLabel; 
@end 

dargli un immobile UILabel * cellLabel, e fare tutto il codice si dispone sopra a parte l'impostazione del testo di etichette nella init di MyCustomCell.m, sostituire tutte le istanze di cella con l'auto, ad esempio:

- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier 
{ 
    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; 

    if (self) 
    { 
     self.cellLabel = [[UILabel alloc] initWithFrame:CGRectMake(20, 10, 120, 35)]; 
     [self.cellLabel setText:txt]; 
     [self.cellLabel setFont:[UIFont boldSystemFontOfSize:12]]; 
     [self.cellLabel setBackgroundColor:[UIColor clearColor]]; 
    } 

    return self; 
} 

Ora nel tuo cellForRowAtIndexPath usare MyCustomCell, dove si controlla se la cella == nil, si potrebbe desiderare di controllare anche l'etichetta della cella:

if(cell == nil || cell.cellLabel == nil) 

inizializzarlo esattamente nello stesso modo:

cell = [[MyCustomCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier]; 

ora, tutto quello che dovete fare è impostare:

cell.cellLabel.text = ....; 

il codice in cellForRowAtIndexPath è molto più pulito, efficiente della memoria e e non sarà possibile ottenere il tuo bug

Ricordate di impostare il vostro cellulare ad essere di tipo MyCustomCell in Interface Builder.

+0

Dice "self" è immutabile in swift ?? – mythicalcoder

4

Questo thread è un po 'più vecchio. Ma sarà utile a qualcuno,

È possibile rimuovere qualsiasi view aggiunto a un cell prima che lo stesso venga riutilizzato nello tableView.

Questo codice lo farà,

for (UIView* view in [cell.contentView subviews]) 
{ 
    if ([view isKindOfClass:[UILabel class]]) //Condition if that view belongs to any specific class  
    { 
     [view removeFromSuperview]; 
    } 
} 

Questo può essere aggiunto prima di configurare il cellulare,

if (!cell) { 
    cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleValue2 reuseIdentifier:CellIdentifier]; 

} 

E 'possibile fare i valori di etichetta della cella a zero per evitare la ripetizione nelle finali cellule.

cell.textLabel.text = nil; 
cell.detailTextLabel.text = nil; 
cell.textLabel.font = nil; 
2

Scrivi questo codice per collectionView. Aiuterà a rimuovere la duplicità dalla cella riutilizzabile.

- (void)viewDidLoad { 
[super viewDidLoad]; 
arrImg=[[NSMutableArray alloc]initWithObjects:@"images.jpeg",@"images-2.jpeg",@"images-3.jpeg", nil]; 

UICollectionViewFlowLayout *flowLayout = [[UICollectionViewFlowLayout alloc] init]; 
[flowLayout setItemSize:CGSizeMake(375, 200)]; 
[flowLayout setScrollDirection:UICollectionViewScrollDirectionVertical]; 

[self.colView setCollectionViewLayout:flowLayout]; 
self.colView.backgroundColor=[UIColor lightGrayColor]; 
self.colView.delegate=self; 
self.colView.dataSource=self; 

// Do any additional setup after loading the view, typically from a nib. 
} 

    -(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath { 


CollectionViewCell1 *cell=(CollectionViewCell1 *)[colView dequeueReusableCellWithReuseIdentifier:@"CollectionViewCell1" forIndexPath:indexPath]; 
float xAxis=0; 
float maxwidth=0; 


for (UIView* view in [cell.contentView subviews]) 
{ 
    if ([view isKindOfClass:[UIScrollView class]]) //Condition if that view belongs to any specific class 
    { 
     [view removeFromSuperview]; 
    } 
} 
if(indexPath.row==1) 
{ 
    UIScrollView *scroll=[[UIScrollView alloc]initWithFrame:CGRectMake(0,0, colView.frame.size.width, 200)]; 

    scroll.delegate = self; 
    [cell.contentView addSubview:scroll]; 

    for(int i=0;i<[arrImg count];i++) 
    { 

    UIImageView *img=[[UIImageView alloc]init]; 
    xAxis=xAxis+maxwidth; 
    img.frame=CGRectMake(xAxis, 0, self.view.frame.size.width, 200); 
    img.image=[UIImage imageNamed:[NSString stringWithFormat:@"%@",[arrImg objectAtIndex:i]]]; 
     [scroll addSubview:img]; 
     maxwidth=self.view.frame.size.width; 
    } 

    scroll.contentSize=CGSizeMake(375*3, 200); 
    scroll.pagingEnabled=YES; 


} 
    return cell; 

}