UITableView marca solo UNA Fila a la vez

Creerías que sería fácil. Con este código, puedo verificar múltiples filas en una tabla, pero lo que QUIERO es solo tener una fila comprobada a la vez. Si un usuario selecciona una fila diferente, quiero que la fila anterior simplemente AUTOMÁTICAMENTE desactive. No se como hacer eso. Aquí está mi código:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { [tableView deselectRowAtIndexPath:indexPath animated:YES]; UITableViewCell *theCell = [tableView cellForRowAtIndexPath:indexPath]; if (theCell.accessoryType == UITableViewCellAccessoryNone) { theCell.accessoryType = UITableViewCellAccessoryCheckmark; } else if (theCell.accessoryType == UITableViewCellAccessoryCheckmark) { theCell.accessoryType = UITableViewCellAccessoryNone; } } 

Gracias por cualquier ayuda que pueda prestar.

La mejor manera es establecer el tipo de accesorio en cellForRowAtIndexPath y usar didSelectRowAtIndexPath para solo registrar qué ruta debe seleccionarse y luego llamar a reloadData.

 - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { [tableView cellForRowAtIndexPath:indexPath].accessoryType = UITableViewCellAccessoryCheckmark; } -(void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath { [tableView cellForRowAtIndexPath:indexPath].accessoryType = UITableViewCellAccessoryNone; } 

Swift versión Swift sería:

 func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) { tableView.cellForRowAtIndexPath(indexPath)?.accessoryType = .Checkmark } func tableView(tableView: UITableView, didDeselectRowAtIndexPath indexPath: NSIndexPath) { tableView.cellForRowAtIndexPath(indexPath)?.accessoryType = .None } 

Actualización Swift 3 :

 func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { tableView.cellForRow(at: indexPath)?.accessoryType = .checkmark } func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) { tableView.cellForRow(at: indexPath)?.accessoryType = .none } 

Puede crear una nueva variable para rastrear el índice seleccionado en didSelectRowAtIndex.

 int selectedIndex; 

en su cellForRowAtIndexPath

 if(indexPath.row == selectedIndex) { cell.accessoryType = UITableViewCellAccessoryCheckmark; } else { cell.accessoryType = UITableViewCellAccessoryNone; } 

y en su didSelectRowAtIndex

 selectedIndex = indexPath.row; [tableView reloadData]; 

No es necesario (y no debería) simplemente recargar la tabla después de cada selección.

Apple tiene buena documentation sobre cómo administrar una list de selección. Vea el listdo 6-3 para ver un ejemplo.

Esto es más o less la misma respuesta que algunos de los otros, pero pensé agregar algunos detalles más.

Lo que quiere hacer es save el IndexPath seleccionado actual en una variable y usar eso en didSelectRowAtIndexPath para eliminar la marca de verificación anterior. También es aquí donde agregará la nueva marca de verificación.

Debe asegurarse de configurar / deshabilitar las marcas de verificación en cellForRowAtIndexPath; de lo contrario, si su list es grande y las células se reutilizan, se verá como si se seleccionan varias filas. Este es un problema con algunas de las otras respuestas.

Vea el ejemplo de Swift 2.0 a continuación:

 // for saving currently seletcted index path var selectedIndexPath: NSIndexPath? = NSIndexPath(forRow: 0, inSection: 0) // you wouldn't normally initialize it here, this is just so this code snip works // likely you would set this during cellForRowAtIndexPath when you dequeue the cell that matches a saved user selection or the default func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) { // this gets rid of the grey row selection. You can add the delegate didDeselectRowAtIndexPath if you want something to happen on deselection tableView.deselectRowAtIndexPath(indexPath, animated: true) // animated to true makes the grey fade out, set to false for it to immediately go away // if they are selecting the same row again, there is nothing to do, just keep it checked if indexPath == selectedIndexPath { return } // toggle old one off and the new one on let newCell = tableView.cellForRowAtIndexPath(indexPath) if newCell?.accessoryType == UITableViewCellAccessoryType.None { newCell?.accessoryType = UITableViewCellAccessoryType.Checkmark } let oldCell = tableView.cellForRowAtIndexPath(selectedIndexPath!) if oldCell?.accessoryType == UITableViewCellAccessoryType.Checkmark { oldCell?.accessoryType = UITableViewCellAccessoryType.None } selectedIndexPath = indexPath // save the selected index path // do whatever else you need to do upon a new selection } func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) // if this is the currently selected indexPath, set the checkmark, otherwise remove it if indexPath == selectedIndexPath { cell.accessoryType = UITableViewCellAccessoryType.Checkmark } else { cell.accessoryType = UITableViewCellAccessoryType.None } } 

No es necesario volver a cargar el tableView.

Vea el siguiente código:

Declare una variable NSIndexPath lastSelectedIndexPath para su class

 - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { if(lastSelectedIndexPath) { UITableViewCell *lastCell = [tableView cellForRowAtIndexPath:lastSelectedIndexPath]; [lastCell setAccessoryView:nil]; } UITableViewCell *currentCell = [tableView cellForRowAtIndexPath:currentIndexPath]; [currentCell setAccessoryView:UITableViewCellAccessoryCheckmark]; lastSelectedIndexPath = indexPath; } 

Creo que https://stackoverflow.com/a/5960016/928599 lo ayudará.
Lo usé y funciona también con deselectRowAtIndexPath.

La forma más sencilla es save el IndexPath seleccionado y comprobarlo en cellForRowAtIndexPath.

adjunto es el código:

paso 1: inicializar selectedIndexPath selectedIndexPath = [[NSIndexPath alloc] init];

paso 2: en cellForRowAtIndexPath

 if([selectedIndexPath isEqual:indexPath]){ [checkMark setHidden:NO]; } else { [checkMark setHidden:YES]; } 

paso 3: en didSelectRowAtIndexPath

 selectedIndexPath = indexPath; [tableView reloadData]; 

Debería funcionar el trabajo pruebe este Njoy 🙂

Prueba esto:

 func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) { if indexPath.section == 1 { // un-select the older row if let selected = self.LastSelected { tableView.cellForRowAtIndexPath(selected)?.accessoryType = .None } // select the new row tableView.cellForRowAtIndexPath(indexPath)?.accessoryType = UITableViewCellAccessoryType.Checkmark self.LastSelected = indexPath } } 

En Swift, el siguiente funciona perfectamente:

 lastSelectedIndexPath = NSIndexPath(forRow: 1, inSection: 0)// Row will be the previous selected row func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { let cell:LabelsSelectionCell = tableView.dequeueReusableCellWithIdentifier("LabelsSelectionCell", forIndexPath: indexPath) as! LabelsSelectionCell cell.setCellLael(labelOptionsArray[indexPath.row]) if lastSelectedIndexPath == indexPath { cell.setCellCheckedStatus(true) } return cell } func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) { if let _ = lastSelectedIndexPath { let lastCell:LabelsSelectionCell = tableView.cellForRowAtIndexPath(lastSelectedIndexPath!) as! LabelsSelectionCell lastCell.setCellCheckedStatus(false) } let currentCell:LabelsSelectionCell = tableView.cellForRowAtIndexPath(indexPath) as! LabelsSelectionCell currentCell.setCellCheckedStatus(true) lastSelectedIndexPath = indexPath tableView.deselectRowAtIndexPath(indexPath, animated: true) } 

Para Swift 3, el siguiente trabajo me ayudó:

 func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { tableVIew.cellForRow(at: indexPath as IndexPath)?.accessoryType = .checkmark } func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) { tableVIew.cellForRow(at: indexPath as IndexPath)?.accessoryType = .none } 
 Swift iOS var checkedIndexPath : NSIndexPath? // table row which row was selected func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath!) { tableView.deselectRowAtIndexPath(indexPath, animated: true) println("Section #\(indexPath.section)! You selected cell #\(indexPath.row)!") if (self.checkedIndexPath != nil) { var cell = tableView.cellForRowAtIndexPath(self.checkedIndexPath!) cell?.accessoryType = .None } var cell = tableView.cellForRowAtIndexPath(indexPath) cell?.accessoryType = .Checkmark self.checkedIndexPath = indexPath }// end tableView 

En Swift 2.0 utilicé esto:

 func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) { if((lastSelectedIndexPath) != nil) { let lastCell = tableView.cellForRowAtIndexPath(lastSelectedIndexPath) lastCell?.accessoryType = UITableViewCellAccessoryType.None } let currentCell = tableView.cellForRowAtIndexPath(indexPath) currentCell?.accessoryType = UITableViewCellAccessoryType.Checkmark lastSelectedIndexPath = indexPath } 

Mi path es anular la selección de otras celdas durante la selección:

 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = .... if condition { cell.accessoryType = .checkmark tableView.selectRow(at: indexPath, animated: false, scrollPosition: UITableViewScrollPosition.bottom) } else { cell.accessoryType = .none } return cell } func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { for row in 0...tableView.numberOfRows(inSection: 0) { if row == indexPath.row {continue} tableView.deselectRow(at: IndexPath(row: row, section: 0), animated: true) } if let cell = tableView.cellForRow(at: indexPath) { cell.accessoryType = .checkmark } } func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) { let cell = tableView.cellForRow(at: indexPath) cell?.accessoryType = .none } 

Esto es lo que surgió cuando tuve este problema.
Este código se implementa en la última versión de Swift, a partir de hoy …
Para get más información y / o el file de extensión, consulte el Github Gist de este fragment.

 override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { if let sip = selectedIndex { tableView.deselectRow(at: sip, animated: false) } selectedIndex = indexPath } override func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) { if selectedIndex?.row == indexPath.row { selectedIndex = nil } } 

probado y resuelto testing esto funcionó perfectamente

agregue esto como variable global

 var selectedIndexPath = NSIndexPath(row: 0, section: 0) 

Agregue esto en el método didselect

  // old one check off if indexPath != selectedIndexPath as IndexPath { let oldCell = categorytable.cellForRow(at: selectedIndexPath as IndexPath) if oldCell?.accessoryView != nil { oldCell?.accessoryView = nil } else { let imageName = "checkmark" let image: UIImageView = UIImageView(image: UIImage(named: imageName)) cell.accessoryView = image } } // the new one on if cell.accessoryView == nil { let imageName = "checkmark" let image: UIImageView = UIImageView(image: UIImage(named: imageName)) cell.accessoryView = image } else { cell.accessoryView = nil }