-didSelectRowAtIndexPath: non essere chiamato


295

Sto scrivendo un'app iOS con una vista tabella all'interno di una vista scheda. Nel mio UITableViewController, ho implementato -tableView:didSelectRowAtIndexPath:, ma quando seleziono una riga in fase di esecuzione, il metodo non viene chiamato. Tuttavia, la visualizzazione tabella viene popolata, quindi so che vengono chiamati altri metodi tableView nel mio controller.

Qualcuno ha qualche idea su cosa avrei potuto rovinare per farlo accadere?


79
inoltre potresti avere un gesto Riconoscitore in cima a UITableView che assorbe la selezione .. (una delle possibilità)
M.Othman,

Fare attenzione se la vista tabella viene popolata, significa che DataSource è ben impostato. La selezione fa parte dei metodi delegati. Quindi forse l'origine dati è ben impostata ma non il delegato!
Thomas Besnehard,

1
Ciao M.Othman, il tuo commento è esattamente ciò che non andava nel mio problema. Sai come far funzionare il riconoscimento dei gesti "con" il UITableView?
yhl

15
Noto che se tocco e tengo premuto, il tocco alla fine chiama -didSelectRowAtIndexPath. Ho capito che il cappello è perché ho un riconoscimento dei gesti di tocco sul tavolo e il gesto deve fallire prima di ricevere il tocco. Sebbene sia strano, l'animazione di selezione della tabella non è influenzata dal riconoscimento dei gesti.
Hlung,

6
Ho avuto lo stesso problema qui e ho avuto la fortunata opportunità di apprendere che non puoi avere un gesto Riconoscitore sopra UITableView. Grazie M. Othman!
vnchopra,

Risposte:


97

Sembra che forse la classe non sia adatta UITableViewDelegatea quella vista tabella, anche se UITableViewControllerdovrebbe impostarla automaticamente.

Qualche possibilità di reimpostare il delegato su un'altra classe?


7
Ho scoperto che mentre il mio controller era un UITableViewController, ho usato un vecchio widget UIViewController in UI Builder. Non funziona Quando ho eliminato il widget UIViewController e lasciato cadere un UITableViewController al suo posto, tutto ha funzionato.
Matt Pfefferle,

1
Un altro caso limite per tutti: ho cablato il delegato in codice e mi ero dimenticato di aver precedentemente collegato il delegato tramite lo storyboard .... l'ultimo a impostarlo vince.
Oliver Dungey,

1
puoi mostrare come "resettare un delegato ad un'altra classe" per favore? Ho lo stesso problema e non riesco a risolverlo
Alfro,

1
myTableViewController.tableView.delegate = xxx
Hunter

534

Nel caso in cui qualcuno abbia commesso lo stesso stupido errore che ho fatto io:

Controlla se il nome del metodo di quello che ti aspetti di essere didSelectpotrebbe essere accidentalmente ottenuto didDeselectin qualche modo. Ci sono volute circa due ore per scoprire ...


47
Lo stesso problema qui. È perché XCode completa automaticamente Deseleziona prima di Seleziona.
user1021430

Allo stesso modo, avevo impostato allowSelection = false, che oltre a rimuovere l'evidenziazione della selezione, impedisce anche di premere la cella!
djinne95,

503

Un'altra cosa che potrebbe causare il problema non è il tipo di selezione selezionato:

Tipo di selezione UITableView

Dovrebbe essere Single Selectionper la selezione normale, non dovrebbe essere No Selection.

Per fare ciò a livello di codice, fai:

tableView.allowsSelection = YES

4
Continuo a correre in questo perché ho scene che sono sempre in modalità di modifica e continuo a dimenticare di cambiare l'impostazione predefinita da "Nessuna selezione durante la modifica".
Simmetrico

3
È possibile aggiungere questa riga nel metodo -viewDidLoad di viewControlller NSParameterAssert (self.tableView.allowsSelection);
Nikolay Shubenkov,

per coloro che hanno osservato tableView.rx.itemSelected.subscribe non hanno richiamato, questo è il problema e le correzioni sopra funzionano
Dhilip

così utile quando si acquisisce un po 'di base di codice e ha il codice usando i pulsanti con i tag e non ha fattoSelectRow, con questa selezione disabilitata nello storyboard 🙄
Nitin Alabur

è questo comportamento predefinito tableView?
Frostmourne,

296

Un'altra possibilità è che un UITapGestureRecognizer possa mangiare gli eventi, come è avvenuto qui: https://stackoverflow.com/a/9248827/214070

Non sospettavo questa causa, perché le celle della tabella continuavano a evidenziare in blu come se i rubinetti passassero.


Questo era il mio problema! Grazie mille!! Voglio dire, chiaramente ha funzionato prima, ma ha smesso di funzionare dopo aver implementato UITapGestureRecognizer * tap = [[UITapGestureRecognizer alloc] initWithTarget: self action: @selector (dismissKeyboard)]; [self.view addGestureRecognizer: tocca];
coolcool1994,

26
Ho avuto lo stesso problema di te @ coolcool1994 appena implementato [tocca setCancelsTouchesInView: NO]; e risolto il problema.
nizx,

Grazie, mi aiuta. Nel mio caso didSelectRowAtIndexPathnon funziona solo dopo aver eliminato la cella in commitEditingStyle. Poi faccio UITapGestureRecognizere tapAction:ottenuto indexPathda sender.view( [self.tableView indexPathForCell:sender.view]) e call[self.tableView.delegate didSelectRowAtIndexPath:myIndexPath]
Alexmelyon

1
Anche questo è stato il mio problema ... aggiungi il codice per rimuovere la tapgesture in tableview ed è stato un lavoro di charme - (UITableViewCell *) tableView: (UITableView *) tableView cellForRowAtIndexPath: (NSIndexPath *) indexPath {UITapGestureRecognizer * gesture = [[UITapGestureRecognizer * gesture = [[UITapGestureRecognizer * gesture = [ ] dentro]; gesture.cancelsTouchesInView = NO; [self.tableView addGestureRecognizer: gesture]; }
Udaya Sri,

6
Grazie @nizx, in 4 rapidi tap.cancelsTouchesInView = false
Ariven Nadar

150

Tutte buone risposte, ma ce n'è ancora una da cercare ...

(Soprattutto quando si crea un UITableView a livello di codice)

Assicurarsi che tableView possa rispondere alla selezione impostando [tableView setAllowsSelection:YES];o rimuovendo qualsiasi riga su cui lo imposta NO.


9
Vorrei aggiungere setAllowsSelectionDuringEditing:all'elenco (quando tableview è in modalità di modifica)
alex-i

Grazie! In IB ho dovuto cambiare il valore della sezione "Selezione" in Single Selection.
Sasho,

90

Se il problema si presenta con UITapGestureRecognizerte puoi risolvere questo:

  • nello Storyboard:

inserisci qui la descrizione dell'immagine

nel codice con Objective-C:

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

[tap setCancelsTouchesInView:NO];

nel codice con Swift:

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

tap.cancelsTouchesInView = false

67

Ho riscontrato due cose in queste situazioni.

  1. Potresti aver dimenticato di implementare il protocollo UITableViewDelegate o non ci sono punti di delega tra la tua classe e la vista della tabella.

  2. Potresti avere un UIView nella tua riga che è un primo risponditore e ti toglie i clic. Pronuncia un pulsante UIB o qualcosa di simile.


5
Ha iniziato a verificarsi su iOS 7, disabilitando "Interazione utente abilitata" delle visualizzazioni all'interno di contentView risolto.
Kof

1
@Kof l'ha inchiodato. La creazione di un UITableViewCell nel builder dell'interfaccia di Xcode 5 lo crea con l'interazione dell'utente abilitata = SÌ. Bad Xcode 5!
jsd

44

Ho avuto lo stesso problema. Ed è stato difficile da trovare. Ma da qualche parte nel mio codice c'era questo:

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

Deve essere return indexPath, altrimenti -tableView:didSelectRowAtIndexPath:non viene chiamato.


2
for did SelectRow At IndexPath la firma corretta è: - (vuoto) tableView: (UITableView *) tableView didSelectRowAtIndexPath: (NSIndexPath *) indexPath {
coolcool1994

Per me, non inizierebbe a chiamare tableView: didSelectRowAtIndexPath fino a quando non avrò eliminato willSelectRowAtIndexPath interamente
etayluz

38

Se hai aggiunto un gestureRecognizer sopra UITableView, didSelectRowAtIndexPathnon verrà chiamato.

Quindi è necessario utilizzare il metodo delegato gestureRecognizer per evitare il tocco in una vista particolare.

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

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

29

Ho riscontrato un problema in cui dopo mesi di non guardare il mio codice ho dimenticato di aver implementato il seguente metodo a causa di alcuni requisiti che non erano necessari

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

Dovrebbe essere restituito SÌ per una riga per renderlo selezionato.


24

DEVI selezionare queste opzioni

inserisci qui la descrizione dell'immagine

ma se non si desidera UITableViewevidenziare facendo clic, è necessario apportare modifiche inUITableViewCell proprietà.

Scegli Nessuna opzione per Selezione proprio come sotto

inserisci qui la descrizione dell'immagine


20

Avevo messo una vista UITapGestureRecognizersul mio tavolo per chiudere la tastiera che impediva didSelectRowAtIndexPath:di essere chiamata. Spero che aiuti qualcuno.



19

Ho avuto lo stesso problema,

Il motivo stava usando UITapGestureRecognizer. Volevo che la tastiera si chiudesse quando toccavo altrove. Mi sono reso conto che questo ha la precedenza su tutte le azioni di tocco, ecco perché,didSelectRowAtIndexPath funzione non ha chiamato.

Quando commento le righe correlate UITapGestureRecognizer, funziona. Inoltre è possibile verificare UITapGestureRecognizer selectorse la funzione è toccata UITableViewCello meno.


14

Nel mio caso, didSelctRowAtIndexPath non chiamando è dovuto al fatto che non ho selezionato nessuno nella proprietà Selezione di tableView, impostato su selezione singola risolto il mio problema

inserisci qui la descrizione dell'immagine


11

Per Xcode 6.4, Swift 1.2. Il "tag" di selezione era stato modificato in IB. Non so come e perché. Impostandolo su "Selezione singola" ho reso nuovamente selezionabili le celle della vista tabella. inserisci qui la descrizione dell'immagine


10

Anche se è stata accettata un'altra risposta, aggiungerò un altro possibile problema e soluzione per le persone che osservano questo problema:

Se il conteggio dei riferimenti automatico (ARC) è attivato, è possibile che anche dopo aver assegnato il controller come delegato della vista, i messaggi della vista al controller non vengano ricevuti perché ARC sta eliminando il controller. Apparentemente il puntatore delegato di UITableView non conta come riferimento per ARC, quindi se questo è l'unico riferimento ad esso, il controller verrà distribuito. È possibile verificare se ciò sta accadendo implementando il metodo dealloc sul controller e impostando lì un breakpoint o una chiamata NSLog.

La soluzione è tenere traccia del controller con un forte riferimento altrove, fino a quando non si è sicuri di non averne più bisogno.


Il controller viene raccolto in modo inutile mentre la sua vista è ancora visualizzata? Questo può davvero succedere?
Drux,

@Drux Yep! Quando questo è successo a me è stata quasi la prima versione di Obj-C con Garbage Collection utilizzata su iOS e onestamente non hanno fatto un ottimo lavoro. Molti riferimenti erano esplicitamente o implicitamente "deboli" che, IMO, avrebbero dovuto essere forti. Ciò ha portato a stranezze come la garbage collection di oggetti in uso attivo da parte del livello di visualizzazione. Non lavoro su iOS da un po 'di tempo, quindi non ho idea se ciò avvenga ancora sull'ultima versione.
Andrew Gorcester,

Il mio codice ha un problema di dimensioni della memoria in aumento e ho risolto un po 'di esso e da qualche altra parte nel codice subito dopo averlo selezionato Selezionare non verrà chiamato solo la prima volta. Non so questo giustifica il problema o no.
Amber K,

10

Ricordarsi di impostare l'origine dati e delegare nel metodo viewDidLoad come segue:

[self.tableView setDelegate:self];

[self.tableView setDataSource:self];

Stavo chiamando l'origine dati ma non delegato ... grazie!
Gmeister4,

9

Il mio problema era nessuno dei precedenti. E così zoppo. Ma ho pensato di elencarlo qui nel caso aiuti qualcuno.

Ho un tableViewControllercontroller di "base", quindi creo sottoclassi di questo controller. Stavo scrivendo tutto il mio codice nella tableView:didSelectRowAtIndexPathroutine nella classe "base". Dimenticando completamente che di default questa routine era stata creata (anche se senza codice che faceva nulla) anche in tutte le mie sottoclassi. Quindi, quando ho eseguito la mia app, ha eseguito la versione della sottoclasse del codice, non ha fatto nulla e mi ha reso triste. Quindi, ovviamente, una volta rimossa la routine dalle sottoclassi, ha usato la routine di classe mt "base" e sono in affari.

Lo so. Non ridere. Ma forse questo salverà qualcuno l'ora che ho perso ...


8

Dare i miei 2 centesimi su questo.

Avevo un UITableViewCell personalizzato e c'era un pulsante che copriva l'intera cella, quindi quando si verificava il tocco, il pulsante veniva selezionato e non la cella.

O rimuovo il pulsante o, nel mio caso, ho impostato Abilitazione interazione utente su false sul pulsante, in questo modo la cella era quella selezionata.


8

Se leggi questo, quindi non risolve ancora il problema.

Ho una cella personalizzata , dove la casella di controllo " Interazione utente abilitata " era disabilitata. Quindi, lo accendo e basta. In bocca al lupo.


7

Ho appena avuto questo e come è successo a me in passato non ha funzionato perché non ho prestato attenzione al completamento automatico quando ho provato ad aggiungere il metodo e in realtà ho finito per implementare tableView:didDeselectRowAtIndexPath: invece di tableView:didSelectRowAtIndexPath:.


7

Assicurati di aver implementato tableView:didSelectRowAtIndexPathe nontableView:didDeSelectRowAtIndexPath

Questo mi ha procurato più di alcune occasioni !!


5

So che è vecchio e il problema è stato risolto, ma un problema simile, ho pensato che il problema fosse con il mio UITableViewCell personalizzato, ma la soluzione era completamente diversa - riavvio XCode :) e quindi funziona bene! quasi come Windows :)


5

Se la vista della tabella è in modalità di modifica (ad es. [tableView setEditing:YES animated:NO];), È necessario impostaretableView.allowsSelectionDuringEditing = YES;


4

Un altro errore che avresti potuto fare (come ho fatto io): se hai impostato un seguito nella cella, didSelectRowAtIndexPathnon viene chiamato. Dovresti invece impostare i tuoi follower sul view controller.


4

Nessuna di queste risposte ha funzionato per me. Dopo circa un'ora, ho capito qualcosa di molto insidioso:

Ho una vista tabella all'interno di una cella di un'altra vista tabella. Ho deciso, tra le altre cose, di creare una vista chiusa che contenga la vista tabella interna. Ho chiamato questa vista contentView e l'ho collegato in xib.

Si scopre che UITableViewCell ha già un contentView e fa cose strane con esso. Il problema si è risolto quando ho rinominato la proprietà in mainContentView e ricollegato la vista a questa proprietà rinominata.


4

Nel mio caso, calcolo dinamicamente l'altezza della TableView's SuperViewal momento del caricamento. A causa di un errore di calcolo, è TableViewstato posizionato all'esterno di SuperView. È TableViewstato disegnato bene, tuttavia tutte le interazioni sono state disabilitate (e didSelectRowAtIndexPathnon sono mai state chiamate). Molto difficile da rilevare, poiché non vi è alcuna indicazione visiva che TableViewnon sia "accessibile".


4

Nel mio caso il problema era che avevo una UITableViewCellsottoclasse e avevo implementato questi due metodi: touchesBegan:withEvent:& touchesEnded:withEventper gestire una fantasia animazione al tatto. Ma avevo dimenticato di aggiungere l' [super touchesBegan:touches withEvent:event];annuncio del metodo [super touchesEnded:touches withEvent:event];per informare anche il genitore della cella del tocco.

Quindi la modifica del codice in seguito ha risolto il mio 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
Posso confermare che questo ha causato in particolare il problema del PO per me
Josh Wolff il

4

Nel mio caso, la soluzione era cambiare NO in SÌ nella funzione seguente.

iOS 9+

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

Anche questo era il mio problema. Ho un'implementazione multipla di tableView e ho dimenticato di separare le due tableview in questo metodo.
Turingtest del
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.