indexPathForSelectedRow devuelve nil

Tengo un UITableViewController con un segue donde bash get la fila actualmente seleccionada:

-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{ if([[segue identifier] isEqualToString:@"EditFilterElementSegue"]){ // Get the element that was clicked and pass it to the view controller for display NSIndexPath *selectedIndexPath = [self.tableView indexPathForSelectedRow]; Element *element = [fetchedResultsController objectAtIndexPath:selectedIndexPath]; FilterElementTableViewController *vc = segue.destinationViewController; vc.filter = filter; vc.element = element; } } 

El problema es indexPathForSelectedRow devuelve nil. Los documentos dicen que nil se devuelve "si la ruta del índice no es válida". Si añado:

  [self.tableView selectRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0] animated:YES scrollPosition:0]; selectedIndexPath = [self.tableView indexPathForSelectedRow]; 

selectedIndexPath es válido. Por lo tanto, actualmente estoy asumiendo que la fila de alguna manera no está seleccionada. ¿Alguien puede decirme cómo averiguar si este es el caso y qué podría estar causándolo?

Este código funcionó bien hasta que me convertí en NSFetchedResultsController (que de lo contrario funciona). También utilizo indexPathForSelectedRow en varios otros controlleres de vista de tabla donde funciona bien (uno de los cuales también usa NSFetchedResultsController).

También he intentado dividir en didSelectRowAtIndexPath, pero sucede lo mismo allí. (esperado ya que se llama después de prepareForSegue).

Una posible causa es que ha escrito algo en uno de los methods UITableViewDelegate :

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

Es una práctica común deselect the row que acaba de ser seleccionada.

Algo que puede ayudar a otros: si llama a reloadData() en su vista de tabla, anula el indexPathForSelectedRow .

Asegúrese de no llamar al método deselectRowAtIndexPath antes de get la ruta de índice de la Fila seleccionada.

 -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { [tableView deselectRowAtIndexPath:indexPath animated:YES]; //add this line after setting indexPath } 

Ok, la conclusión es que la escena en el storyboard estaba en mal estado.

Para resolverlo eliminé el segue y creé una nueva class vacía UITableViewController y solo agregué suficiente código para poder hacer clic en una fila y mirar indexPathForSelectedRow. Todavía era nulo.

Luego creé un nuevo UITableViewController en storyboard y reemplazé el existente. Ahora indexPathForSelectedRow funcionó.

Copié todo el código de class y las celdas prototipo, ¡y aún funcionó!

Por curiosidad, miré la fuente del guión gráfico para las dos escenas y noté que la escena que no funcionaba era mucho más larga que la nueva. Mirando el esquema del guión gráfico, era obvio por qué, y sorprendente, funcionó en absoluto. Y ahora recuerdo haber tenido problemas para cortar y pegar un prototipo de celda. Supongo que debería mirar el modo de contorno con mayor frecuencia. Mira la captura de pantalla a continuación (las escenas visuales se ven iguales):

Storyboard captura de pantalla

Ok En mi caso, llamé desde UIButton en storyboard por show segue.

Y eliminando la siguiente línea:

NSIndexPath *indexPath = [self.tableView indexPathForCell:sender];

con less de 2 líneas trabajadas para mí:

CGPoint buttonPosition = [sender convertPoint:CGPointZero toView:self.tableView]; NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:buttonPosition];

Espero que con mi caso "llamar segue desde UIButton on CELL" también funcione para otros.

También tuve este problema, cuando reemplacé una class UITableViewController con una class UIViewController en código, y no actualicé el storyboard, es decir, no reemplacé el marcador de position UITableViewController en storyboard, con un storyboard de UIViewController.