UITableView Checkmark SÓLO UNA fila a la vez

Pensarías que esto sería fácil. Con este código, puedo verificar varias filas en una tabla, pero lo que QUIERO es tener solo una fila marcada a la vez. Si un usuario selecciona una fila diferente, entonces quiero que la antigua fila simplemente se desmarque AUTOMÁTICAMENTE. No sé cómo 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 puedan prestar!

La mejor manera es establecer el tipo de accesorio en cellForRowAtIndexPath y usar didSelectRowAtIndexPath para registrar solo qué ruta se debe seleccionar 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:

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

Actualización de Swift 3 :

 override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { tableView.cellForRow(at: indexPath)?.accessoryType = .checkmark } override 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 tu cellForRowAtIndexPath

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

y en su didSelectRowAtIndex

 selectedIndex = indexPath.row; [tableView reloadData]; 

No necesita (y no debe) simplemente recargar la tabla después de cada selección.

Apple tiene buena documentación sobre cómo administrar una lista de selección. Vea el Listado 6-3 para un ejemplo.

Esta es más o menos la misma respuesta que algunas de las otras pero pensé que agregaría un poco más de detalle.

Lo que quiere hacer es guardar el IndexPath seleccionado actual en una variable y usarlo en didSelectRowAtIndexPath para eliminar la marca de verificación anterior. Aquí también agregará la nueva marca de verificación.

También debe asegurarse de configurar / desactivar las marcas de verificación en cellForRowAtIndexPath; de lo contrario, si su lista es grande y las celdas se reutilizan, se verá como si se hubieran seleccionado varias filas. Este es un problema con algunas de las otras respuestas.

Vea el siguiente ejemplo de swift 2.0:

 // 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 necesita volver a cargar TableView.

Vea el siguiente código:

Declare una variable NSIndexPath lastSelectedIndexPath para su clase

 - (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 te ayudará.
Lo usé y también funciona con deselectRowAtIndexPath!

La forma más simple es guardar el IndexPath seleccionado y verificarlo en cellForRowAtIndexPath.

adjunto está 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, prueba 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 siguiente funcionó para mí:

 override func viewDidLoad() { super.viewDidLoad() // allow cells to be selected tableView.allowsSelection = true // ensure that deselect is called on all other cells when a cell is selected tableView.allowsMultipleSelection = false } 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 camino es deseleccionar 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 obtener más información y / o el archivo de extensión, consulte Github Gist de este fragmento.

 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 intente esto funcionó perfectamente

agregar 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 }