¿Por qué no se llama a -didDeselectRowAtIndexPath?

Creé un proyecto nuevo (Xcode 4, aplicación Master-Detail) solo para ver si estoy haciendo algo mal, pero todavía tengo el mismo problema. Quiero llamar a -reloadData cuando el usuario anula la selección de una celda, por lo que este es mi código:

 - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { [tableView deselectRowAtIndexPath:indexPath animated:YES]; NSLog(@"%s", __PRETTY_FUNCTION__); } -(void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath { NSLog(@"%s", __PRETTY_FUNCTION__); [tableView reloadData]; } -(NSIndexPath *)tableView:(UITableView *)tableView willDeselectRowAtIndexPath:(NSIndexPath *)indexPath { NSLog(@"%s", __PRETTY_FUNCTION__); return indexPath; } 

El problema es que didDeselectRowAtIndexPath y willDeselectRowAtIndexPath no parecen ser llamados. ¿Es este el comportamiento esperado? Los documentos para tableView:didDeselectRowAtIndexPath: estado

Le dice al delegado que la fila especificada ahora está deseleccionada.

así que supongo que debería funcionar como yo pensaba.

la documentación de tableView:willDeselectRowAtIndexPath: también dice que

Este método solo se llama si hay una selección existente cuando el usuario intenta seleccionar una fila diferente. El delegado se envía este método para la fila seleccionada previamente. Puede usar UITableViewCellSelectionStyleNone para deshabilitar la apariencia de la celda resaltada en el toque descendente.

No funcionó para nosotros cuando utilicé UITableViewCellSelectionStyleNone .

Si llama deselectRowAtIndexPath:animated: los métodos delegates tableView:willDeselectRowAtIndexPath: y tableView:didDeselectRowAtIndexPath: mensaje no se envían.

Otra peculiaridad que he encontrado – en IOS 5.1, en cualquier caso – es que si llamas a reloadData en la mesa, no obtendrás didDeselectRowAtIndexPath para ninguna de las filas seleccionadas. En mi caso, ajusto el diseño de la celda un poco dependiendo de si está seleccionado o no, así que tuve que hacer ese trabajo manualmente antes de volver a cargar los datos de la tabla.

Sé que esta es una vieja pregunta, pero me encontré con el mismo problema.

Si utiliza

 [tableView reloadData] 

Luego, los datos de la tabla se vuelven a cargar y no se seleccionan filas detrás de las escenas, lo que significa

solamente

 didSelectRowAtIndexPath 

alguna vez se llama. Espero que esto ayude a alguien que se encuentre con este problema.

Una forma limpia de resolver este problema es hacer lo siguiente:

 func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCellWithIdentifier("myCell", forIndexPath: indexPath) // Do your cell setup work here... //If your cell should be selected... if cellShouldBeSelected { tableView.selectRowAtIndexPath(indexPath, animated: false, scrollPosition: UITableViewScrollPosition.None) } return cell } 

Esto resuelve todo el problema de que una celda no responda a su deselección después de que se tableView.reloadData() una tableView.reloadData() a tableView.reloadData() .

Cuando se selecciona cualquier celda la primera vez, no se llama al método -[UITableViewDelegate tableView:didDeselectRowAtIndexPath:] , pero -[UITableViewDelegate tableView:didSelectRowAtIndexPath:] . Justo después de seleccionar una celda más, se llama a didDeselectRowAtIndexPath justo después de didSelectRowAtIndexPath .

Esto esta bien.

Pero si tiene que mostrar una celda como se seleccionó al principio, (eq usando UITableViewCellAccessoryCheckmark ), entonces, después de seleccionar otra celda, probablemente desee didDeselectRowAtIndexPath método didDeselectRowAtIndexPath primera vez, para anular la selección de la celda anterior.

¡La solución!

-[UITableView selectRowAtIndexPath:animated:scrollPosition:] llamar a -[UITableView selectRowAtIndexPath:animated:scrollPosition:] en -[UITableViewDataSource tableView:cellForRowAtIndexPath:] para notificar que ya se ha seleccionado una celda deseada.

C objective

 #pragma mark - UITableViewDelegate - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath]; cell.accessoryType = UITableViewCellAccessoryCheckmark; // saving the current selected row SelectedRow = indexPath.row; } - (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath { UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath]; cell.accessoryType = UITableViewCellAccessoryNone; } #pragma mark - UITableViewDataSource - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell"]; if (!cell) { cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"cell"]; } // preventing selection style cell.selectionStyle = UITableViewCellSelectionStyleNone; cell.textLabel.text = "Some text"; if (indexPath.row == SelectedRow) { cell.accessoryType = UITableViewCellAccessoryCheckmark; // just wanted to make it selected, but it also can scroll to the selected position [tableView selectRowAtIndexPath:indexPath animated:NO scrollPosition:UITableViewScrollPositionNone]; } return cell; } 

Swift 3.1

 // MARK: - UITableViewDelegate override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { let cell = tableView.cellForRow(at: indexPath)! cell.accessoryType = UITableViewCellAccessoryType.checkmark selectedRow = indexPath.row } override func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) { let cell = tableView.cellForRow(at: indexPath)! cell.accessoryType = UITableViewCellAccessoryType.none } // MARK: - UITableViewDataSource override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = UITableViewCell(style: UITableViewCellStyle.default, reuseIdentifier: "cell") // preventing selection style cell.selectionStyle = UITableViewCellSelectionStyle.none cell.textLabel?.text = "some text" if (indexPath.row == selectedRow) { cell.accessoryType = UITableViewCellAccessoryType.checkmark // just wanted to make it selected, but it also can scroll to the selected position tableView.selectRow(at: indexPath, animated: false, scrollPosition: UITableViewScrollPosition.none) } return cell } 

Establezca allowsMultipleSelection para que la vista de tabla sea TRUE

  self.tableView.allowsMultipleSelection = YES; 

¡Creo que es un simple error! ¿Por qué no usas lo siguiente?

 [self.tableView deselectRowAtIndexPath:indexPath animated:YES]; 

¿En lugar de usar solo “tableView” en esa línea?
¡Supongo, y estoy seguro de que la línea superior te daría la solución!
¡Espero que esto te haya ayudado, si miras atrás a tu vieja pregunta!
¡Prestigio! 🙂