2014-05-18 17 views
15

Ho un UITableView che visualizza segni di spunta quando viene selezionata una riga. Il problema è che quando seleziono una riga in didSelectRowAtIndexPath e aggiungo un segno di spunta sulla riga selezionata, aggiunge un segno di spunta aggiuntivo. Ecco il mio codiceSegno di spunta multiplo quando riga selezionata in UITableView IOS

Qualsiasi aiuto sarebbe molto apprezzato.

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell" forIndexPath:indexPath]; 

    // Configure the cell... 

    cell.textLabel.text=[[Model.category objectAtIndex:indexPath.row] categoryName]; 

    cell.imageView.image=[[Model.category objectAtIndex:indexPath.row]categoryImage]; 

    //cell.detailTextLabel.text [email protected]"Breve Descripción de la categoria"; 

    return cell; 

} 

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ 

    if ([self.tableView cellForRowAtIndexPath:indexPath].accessoryType == UITableViewCellAccessoryCheckmark) { 

[self.tableView cellForRowAtIndexPath:indexPath].accessoryType =UITableViewCellAccessoryNone; 

[self.cellSelected removeObject:indexPath]; 

    }else { 

    [tableView cellForRowAtIndexPath:indexPath].accessoryType=UITableViewCellAccessoryCheckmark; 

     [self.cellSelected addObject:indexPath]; 

    } 

    [self checkMark]; 

    [tableView reloadData]; 
} 

- (void)checkMark{ 

    for (NSIndexPath * indexPath in self.cellSelected) { 

     [self.tableView cellForRowAtIndexPath:indexPath].accessoryType=UITableViewCellAccessoryCheckmark; 

    } 


} 

risposta

41

[self.tableView cellForRowAtIndexPath:indexPath] la chiamata nel didSelectRowAtIndexPath non restituirà la cella esatta. Può essere la stessa cella, una nuova cella o una cella riutilizzata. Se è una cella riutilizzata nella sua vista accessoria ha un segno di spunta, finirà per avere due celle con segno di spunta.

È meglio memorizzare nell'array e utilizzarlo di conseguenza. Se si prevede di avere selezioni multiple, utilizzare l'esempio di codice riportato di seguito.

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 

// Do any additional setup after loading the view, typically from a nib. 
    self.cellSelected = [NSMutableArray array]; 
} 


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    //Cell Initialisation here 

    if ([self.cellSelected containsObject:indexPath]) 
    { 
     cell.accessoryType = UITableViewCellAccessoryCheckmark; 
    } 
    else 
    { 
     cell.accessoryType = UITableViewCellAccessoryNone; 

    } 
    return cell; 
} 


- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    [tableView deselectRowAtIndexPath:indexPath animated:YES]; 
    //if you want only one cell to be selected use a local NSIndexPath property instead of array. and use the code below 
    //self.selectedIndexPath = indexPath; 

    //the below code will allow multiple selection 
    if ([self.cellSelected containsObject:indexPath]) 
    { 
     [self.cellSelected removeObject:indexPath]; 
    } 
    else 
    { 
     [self.cellSelected addObject:indexPath]; 
    } 
    [tableView reloadData]; 
} 
+0

perché [tableView deselectRowAtIndexPath: indexPath animato: SI] necessario ?? quando commento questa frase funziona anche bene. – Klinkert0728

+0

Ho lo stesso problema, ma con un'immagine, ho un'immagine per ogni cella e quando seleziono una riga ho bisogno di cambiare l'immagine della riga selezionata, ma quando cambio questa immagine, forse cambierà un'altra immagine mi puoi aiutare – Klinkert0728

+0

deselezionare è rimuovere il comportamento evidenziato quando tocchi la cella. –

4

Prova questo:

Declare nel file .m:

@interface MyViewController() { 
     NSIndexPath *__selectedPath; 
    } 

In tableView:cellForRowAtIndexPath: controllo se dato indexPath è lo stesso memorizzato in Ivar:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {  
    //configure cell 

    if ([__selectedPath isEqual:indexPath]) { 
     cell.accessoryType = UITableViewCellAccessoryCheckmark; 
    } else { 
     cell.accessoryType = UITableViewCellAccessoryNone; 
    } 

    return cell; 
} 

In tableView:didSelectRowAtIndexPath puntatore archivio su NSIndexPath o nil selezionato se la cella è stata desel ect

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 

    if (cell.accessoryType == UITableViewCellAccessoryNone) { 
     cell.accessoryType = UITableViewCellAccessoryCheckmark; 
     __selectedPath = indexPath; 
    } else { 
     cell.accessoryType = UITableViewCellAccessoryNone; 
     __selectedPath = nil; 
    } 
} 

ho scritto senza controllare in Xcode, quindi ci potrebbero essere alcuni errori di battitura, ma mostrano idea principale. Secondo me non si dovrebbe chiamare [self checkMark]; nel proprio metodo tableView:cellForRowAtIndexPath:.

Inoltre, se si desidera avere solo una cella selezionata alla volta, non è necessario creare NSMutableArray per memorizzare NSIndexPath. Sembra il tuo cellSelected negozi 2 NSIndexPaths alla volta, questo è il motivo per cui hai questo strano comportamento.

+0

Grazie mille, ma ho bisogno di chiamare il metodo checkMark perché ho un array Mutable con indexPath a seconda di quale cella è stata selezionata e ho bisogno di quelle celle con segno di spunta. Sono nuovo con tutto questo spero che tu possa aiutarmi. – Klinkert0728

+0

Se si desidera avere solo una cella selezionata in una volta, non utilizzare NSMutableArray. Solo NSIndexPath. NSMutableArray occupa molto più spazio in memoria, quindi non è necessario utilizzarlo qui. Inoltre, quando si utilizza NSIndexPath, si sarà sicuri che verrà memorizzato un solo puntatore a NSIndexPath e durante la tabella di visualizzazione dei dati di ricaricamento verrà selezionato solo uno o zero UITableViewCell. – Neru

8

Basta usare didSelectRowAtIndexPath e didDeselectRowAtIndexPath metodi e il vostro tavolo esempio View Controller.

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ 

    [[self.tableView cellForRowAtIndexPath:indexPath] setAccessoryType:UITableViewCellAccessoryCheckmark]; 
} 

-(void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath { 

    [[self.tableView cellForRowAtIndexPath:indexPath] setAccessoryType:UITableViewCellAccessoryNone]; 
} 
+2

Per quanto mi sembra, questo metodo funzionerà fintanto che la cella non viene riutilizzata. Quando la cella verrà riutilizzata, tutto sarà confuso. – Vive

Problemi correlati