-didSelectRowAtIndexPath: no se llama


295

Estoy escribiendo una aplicación de iOS con una vista de tabla dentro de una vista de pestaña. En mi UITableViewController, implementé -tableView:didSelectRowAtIndexPath:, pero cuando selecciono una fila en tiempo de ejecución, no se llama al método. Sin embargo, la vista de tabla se está completando, por lo que sé que se están llamando a otros métodos tableView en mi controlador.

¿Alguien tiene alguna idea de lo que he jodido para que esto suceda?


79
también puede tener un gesto Reconocimiento en la parte superior de UITableView que absorbe la selección ... (una de las posibilidades)
M.Othman

Tenga cuidado si la vista de tabla se está completando, significa que DataSource está bien configurado. La selección es parte de los métodos Delegado. ¡Quizás el DataSource esté bien configurado pero no el Delegado!
Thomas Besnehard

1
Hola M.Othman, su comentario es exactamente lo que estaba mal con mi propio problema. ¿Sabes cómo hacer que GestorReconocidor funcione 'con' el UITableView?
yhl

15
Noto que si toco y mantengo presionado, el toque finalmente llama -didSelectRowAtIndexPath. Descubrí los sombreros porque tengo un reconocedor de gestos de toque en la vista de la mesa y el gesto tiene que fallar primero antes de recibir el toque. Aunque es extraño, la animación de selección de tabla no se ve afectada por el reconocedor de gestos.
Hlung

66
Tuve el mismo problema aquí y tuve la afortunada oportunidad de aprender que no se puede tener un gesto Reconocidor encima de UITableView. Gracias M. Othman!
vnchopra

Respuestas:


97

Parece que tal vez la clase no es UITableViewDelegatepara esa vista de tabla, aunque UITableViewControllerse supone que establece eso automáticamente.

¿Hay alguna posibilidad de restablecer el delegado a alguna otra clase?


77
Descubrí que, si bien mi controlador era un UITableViewController, utilicé un viejo widget UIViewController en UI Builder. Eso no funciona Cuando eliminé el widget UIViewController y coloqué un UITableViewController en su lugar, todo funcionó.
Matt Pfefferle

1
Otro caso límite para todos: conecté el delegado en código y olvidé que había conectado previamente al delegado a través del guión gráfico ... el último en configurarlo gana.
Oliver Dungey

1
¿puede mostrar cómo "restablecer un delegado a otra clase" por favor? Tengo este mismo problema y no puedo resolverlo
Alfro

1
myTableViewController.tableView.delegate = xxx
Hunter

534

Por si alguien cometió el mismo error estúpido que yo:

Verifique si el nombre del método de lo que espera ser didSelectpuede ser obtenido accidentalmente didDeselectde alguna manera. Me llevó unas dos horas descubrirlo ...


47
Mismo problema aquí. Es porque XCode completa automáticamente la Deselección antes de Seleccionar.
user1021430

Del mismo modo, configuré allowSelection = false, que además de eliminar cualquier selección resaltada, ¡también evita que se presione la celda!
djinne95

503

Otra cosa que podría conducir al problema no es el tipo de selección seleccionado:

Tipo de selección UITableView

Debería ser Single Selectionpara la selección normal, no debería ser No Selection.

Para hacer esto mediante programación, haga:

tableView.allowsSelection = YES

44
Me encuentro con esto porque tengo escenas que siempre están en modo de edición y me olvido de cambiar el valor predeterminado de "Sin selección durante la edición".
Simétrico

3
Puede agregar esta línea en su método -viewDidLoad de viewControlller NSParameterAssert (self.tableView.allowsSelection);
Nikolay Shubenkov

para aquellos que observaron que tableView.rx.itemSelected.subscribe no devolvió la llamada, este es el problema y la solución anterior funciona
Dhilip

es muy útil cuando se hace cargo de una base de código y tiene código usando botones con etiquetas y no hizo SelectRow, con esta selección deshabilitada en el guión gráfico 🙄
Nitin Alabur

¿Es este comportamiento predeterminado de tableView?
Frostmourne

296

Otra posibilidad es que un UITapGestureRecognizer podría estar comiendo los eventos, como fue el caso aquí: https://stackoverflow.com/a/9248827/214070

No sospeché esta causa, porque las celdas de la tabla aún se resaltarían en azul como si los grifos estuvieran llegando.


Este fue mi problema! ¡¡Muchas gracias!! Quiero decir que claramente funcionó antes, pero dejó de funcionar después de implementar UITapGestureRecognizer * tap = [[UITapGestureRecognizer alloc] initWithTarget: self action: @selector (dispatsKeyboard)]; [self.view addGestureRecognizer: toque];
coolcool1994

26
Tuve el mismo problema que usted @ coolcool1994 acaba de implementar [toque setCancelsTouchesInView: NO]; y resolvió el problema.
nizx

Gracias me ayuda. En mi caso didSelectRowAtIndexPath, no funciona solo después de eliminar la celda commitEditingStyle. Entonces hago UITapGestureRecognizery tapAction:tengo indexPathde sender.view( [self.tableView indexPathForCell:sender.view]) y la llamada[self.tableView.delegate didSelectRowAtIndexPath:myIndexPath]
Alexmelyon

1
Este también fue mi problema ... agregue código para eliminar la tapgestura en tableview y funcionó como encanto - (UITableViewCell *) tableView: (UITableView *) tableView cellForRowAtIndexPath: (NSIndexPath *) indexPath {UITapGestureRecognizer * gest = = [UITapGestureRecognizer alloc ] en eso]; gest.cancelsTouchesInView = NO; [self.tableView addGestureRecognizer: gesto]; }
Udaya Sri

66
Gracias @nizx, en rápido 4 tap.cancelsTouchesInView = false
Ariven Nadar

150

Todas buenas respuestas, pero hay una más a tener en cuenta ...

(Particularmente cuando se crea un UITableView programáticamente)

Asegúrese de que tableView puede responder a la selección configurando [tableView setAllowsSelection:YES];o eliminando cualquier línea que lo configure NO.


99
Añadiría setAllowsSelectionDuringEditing:a la lista (cuando tableview está en modo de edición)
alex-i

¡Gracias! En IB tuve que cambiar en el valor de la sección "Selección" a Single Selection.
Sasho

90

Si surge el problema con UITapGestureRecognizerusted, puede solucionar esto:

  • en Storyboard:

ingrese la descripción de la imagen aquí

en código con Objective-C:

UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(dismissKeyboard)]; 
[self.view addGestureRecognizer:tap];

[tap setCancelsTouchesInView:NO];

en código con Swift:

let tap = UITapGestureRecognizer(target: self, action:Selector("dismissKeyboard"))
view.addGestureRecognizer(tap)

tap.cancelsTouchesInView = false

67

Me he encontrado con dos cosas en estas situaciones.

  1. Es posible que haya olvidado implementar el protocolo UITableViewDelegate, o no hay una salida de delegación entre su clase y su vista de tabla.

  2. Es posible que tenga una UIView dentro de su fila que es el primero en responder y le quita sus clics. Diga un UIButton o algo similar.


55
Comenzó a suceder en iOS 7, deshabilitando "La interacción del usuario habilitada" de las vistas dentro de contentView solucionó esto.
Kof

1
@Kof lo clavó. Crear un UITableViewCell en el generador de interfaces de Xcode 5 lo crea con la interacción del usuario habilitada = SÍ. ¡Mal Xcode 5!
jsd

44

Yo he tenido el mismo problema. Y fue difícil de encontrar. Pero en algún lugar de mi código fue esto:

- (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    return nil;
}

Debe ser return indexPath, de lo contrario -tableView:didSelectRowAtIndexPath:no se llama.


2
para did SelectRow At IndexPath la firma correcta es: - (nulo) tableView: (UITableView *) tableView didSelectRowAtIndexPath: (NSIndexPath *) indexPath {
coolcool1994

Para mí, no comenzaría a llamar a tableView: didSelectRowAtIndexPath hasta que eliminé willSelectRowAtIndexPath por completo
etayluz

38

Si agregó un gesto Reconocimiento encima de UITableView, didSelectRowAtIndexPathno se le llamará.

Por lo tanto, debe usar el método de delegado de gestorReconocidor para evitar tocar en una vista particular.

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
    if ([touch.view isDescendantOfView:YourTable]) {
        return NO;
    }
    return YES;
}

3
if ([touch.view isDescendantOfView:YourTable])
Sudheesh

29

Me encontré con un problema en el que después de meses de no mirar mi código, olvidé que implementé el siguiente método debido a algunos requisitos que no eran necesarios.

- (BOOL)tableView:(UITableView *)tableView shouldHighlightRowAtIndexPath:(NSIndexPath  *)indexPath{
    return NO;
}

Debería devolver YES para una fila para que se seleccione.


24

DEBE seleccionar estas opciones

ingrese la descripción de la imagen aquí

pero si desea que UITableViewno se resalte al hacer clic, debe realizar cambios en las UITableViewCellpropiedades.

Elija la opción Ninguno para la selección como se muestra a continuación

ingrese la descripción de la imagen aquí


20

Había puesto una UITapGestureRecognizervista de mi mesa para descartar el teclado que impedía didSelectRowAtIndexPath:que me llamaran. Espero que ayude a alguien.



19

Yo tuve el mismo problema,

La razón estaba usando UITapGestureRecognizer. Quería descartar el teclado cuando tocaba en cualquier otro lugar. Me di cuenta de que esto anula todas las acciones de tap, es por eso didSelectRowAtIndexPathque no se llamó a la función.

Cuando comento las filas relacionadas UITapGestureRecognizer, funciona. Además, puede verificar la función de UITapGestureRecognizer selectorsi el golpeado es UITableViewCello no.


14

En mi caso, didSelctRowAtIndexPath no llama debido a que no he seleccionado ninguno en la propiedad Selection de tableView, establecer en selección única resolvió mi problema

ingrese la descripción de la imagen aquí


11

Para Xcode 6.4, Swift 1.2. La selección "etiqueta" había cambiado en IB. No sé cómo y por qué. Establecerlo en "Selección única" hizo que mis celdas de vista de tabla fueran seleccionables nuevamente. ingrese la descripción de la imagen aquí


10

Aunque se ha aceptado otra respuesta, agregaré un posible problema y una solución más para las personas que observan este problema:

Si tiene activado el conteo automático de referencias (ARC), puede encontrar que incluso después de asignar su controlador como delegado de la vista, los mensajes de la vista al controlador no se reciben porque ARC está eliminando el controlador. Aparentemente, el puntero de delegado de UITableView no cuenta como una referencia para el ARC, por lo que si esa es la única referencia, el controlador será desasignado. Puede verificar si esto está sucediendo o no implementando el método dealloc en el controlador y estableciendo un punto de interrupción o una llamada NSLog allí.

La solución es hacer un seguimiento del controlador con una referencia fuerte en otro lugar, hasta que esté seguro de que ya no lo necesitará.


¿El controlador se está recolectando basura mientras su vista todavía se muestra? ¿Puede esto realmente suceder?
Drux

@Drux ¡Sí! Cuando esto me sucedió, era casi la primera versión de Obj-C con recolección de basura utilizada en iOS y, sinceramente, no hicieron un gran trabajo. Muchas referencias eran explícita o implícitamente "débiles" que, en mi opinión, deberían haber sido fuertes. Lo que condujo a rarezas como la recolección de basura de objetos en uso activo por la capa de visualización. No he hecho el trabajo de iOS en un tiempo, así que no tengo idea de si esto todavía sucede en la última versión.
Andrew Gorcester

Mi código tiene un problema de tamaño de memoria cada vez mayor y lo arreglé un poco y en algún otro lugar del código justo después de que esto no se llamara a SelectSelect solo la primera vez. No sé si esto justifica el problema o no.
Amber K

10

Recuerde configurar el origen de datos y delegar en el método viewDidLoad de la siguiente manera:

[self.tableView setDelegate:self];

[self.tableView setDataSource:self];

Estaba llamando a fuente de datos pero no delegado ... ¡gracias!
Gmeister4

9

Mi problema no fue ninguno de los anteriores. Y tan cojo. Pero pensé en enumerarlo aquí en caso de que ayude a alguien.

Tengo un tableViewControllerque es mi controlador "base" y luego creo subclases de este controlador. Estaba escribiendo todo mi código en la tableView:didSelectRowAtIndexPathrutina en la clase "base". Olvidando completamente que, por defecto, esta rutina también se había creado (aunque sin código que hiciera nada) en todas mis subclases. Entonces, cuando ejecuté mi aplicación, ejecutó la versión de subclase del código, no hizo nada y me puso triste. Entonces, por supuesto, una vez que eliminé la rutina de las subclases, usé la rutina de clase mt "base" y estoy en el negocio.

Lo sé. No te rías Pero tal vez esto le ahorrará a alguien la hora que perdí ...


8

Dando mis 2 centavos en esto.

Tenía un UITableViewCell personalizado y había un botón que cubría toda la celda, por lo que cuando se tocó, se seleccionó el botón y no la celda.

Quite el botón o, en mi caso, configuré la habilitación de la interacción del usuario en falso en el botón, de esa manera la celda fue la seleccionada.


8

Si lees esto, todavía no resuelve el problema.

Tengo una celda personalizada , donde la casilla de verificación " Interacción del usuario habilitada " estaba deshabilitada. Entonces, solo lo enciendo. Buena suerte.


7

Acabo de tener esto y, como me ha sucedido en el pasado, no funcionó porque no presté atención al autocompletado al intentar agregar el método y en realidad terminé implementando tableView:didDeselectRowAtIndexPath: en lugar de tableView:didSelectRowAtIndexPath:.


7

Asegúrese de implementar tableView:didSelectRowAtIndexPathy notableView:didDeSelectRowAtIndexPath

¡Esto me ha conseguido en más de unas pocas ocasiones!


5

Sé que es viejo y el problema se resolvió, pero tenía un problema similar, pensé que el problema estaba con mi UITableViewCell personalizado, pero la solución era completamente diferente: reinicio XCode :) y luego funciona bien. casi como Windows :)


5

Si su vista de tabla está en modo de edición (p. Ej. [tableView setEditing:YES animated:NO];), Debe configurartableView.allowsSelectionDuringEditing = YES;


4

Otro error que podría haber cometido (como lo hice): si establece un segue en la celda, didSelectRowAtIndexPathno se llama. En su lugar, debe establecer sus valores en el controlador de vista.


4

Ninguna de estas respuestas funcionó para mí. Después de aproximadamente una hora, descubrí algo muy insidioso:

Tengo una vista de tabla dentro de una celda de otra vista de tabla. Decidí hacer una vista envolvente que contenga la vista de tabla interna, entre otras cosas. Llamé a esta vista contentView y la conecté en el xib.

Resulta que UITableViewCell ya tiene un contentView y hace cosas raras con él. El problema se resolvió por sí solo cuando cambié el nombre de la propiedad a mainContentView y volví a conectar la vista a esta propiedad renombrada.


4

En mi caso, calculo dinámicamente la altura de la TableView's SuperViewen el tiempo de carga. Debido a un error de cálculo, TableViewse colocó fuera de la SuperView. Se TableViewdibujó bien, sin embargo, toda la interacción se deshabilitó (y didSelectRowAtIndexPathnunca se llamó). Muy difícil de detectar, ya que no hay indicación visual de que TableViewno sea "accesible".


4

En mi caso, el problema era que tenía una UITableViewCellsubclase y había implementado estos dos métodos: touchesBegan:withEvent:y touchesEnded:withEventmanejar una animación elegante al tacto. Pero olvidé agregar el [super touchesBegan:touches withEvent:event];método publicitario[super touchesEnded:touches withEvent:event]; para informar también al padre de la celda del toque.

Entonces, cambiar el código a siguiente resolvió mi problema:

-(void) touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event{
    [super touchesBegan:touches withEvent:event];
    //blah blah blah
}

-(void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
    [super touchesEnded:touches withEvent:event];
    //rest of the code
}

1
Puedo confirmar que esto me causó el problema del OP en particular
Josh Wolff

4

En mi caso, la solución fue cambiar NO a SÍ en la siguiente función.

iOS 9+

- (BOOL)tableView:(UITableView *)tableView shouldHighlightRowAtIndexPath:(NSIndexPath *)indexPath
{
    return YES;
}

Este fue mi problema también. Tengo una implementación de múltiples vistas de tabla y olvidé separar las dos vistas de tabla en este método.
probado el
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.