Ich schreibe eine iOS-App mit einer Tabellenansicht in einer Tabulatoransicht. In meiner UITableViewController
habe ich -tableView:didSelectRowAtIndexPath:
implementiert, aber wenn ich zur Laufzeit eine Zeile auswähle, wird die Methode nicht aufgerufen. Die Tabellenansicht wird zwar aufgefüllt, daher weiß ich, dass andere tableView-Methoden in meinem Controller aufgerufen werden.
Hat jemand irgendwelche Ideen, was ich vermasselt habe, um dies zu erreichen?
Es klingt, als sei die Klasse möglicherweise nicht die UITableViewDelegate
für diese Tabellenansicht, obwohl UITableViewController
das automatisch festlegen soll.
Gibt es eine Chance, dass Sie den Delegierten auf eine andere Klasse zurücksetzen?
Nur für den Fall, dass jemand den gleichen dummen Fehler gemacht hat wie ich:
Prüfen Sie, ob der Methodenname der von Ihnen erwarteten Variable didSelect
auf irgendeine Weise versehentlich didDeselect
erhalten werden kann. Es hat ungefähr zwei Stunden gedauert, bis ich herausgefunden habe ...
Eine andere Sache, die zu dem Problem führen könnte, ist nicht die Auswahlart:
Sollte Single Selection
für die normale Auswahl sein, sollte nicht No Selection
sein.
Eine andere Möglichkeit ist, dass ein UITapGestureRecognizer die Ereignisse abfragt, wie dies hier der Fall war: https://stackoverflow.com/a/9248827/214070
Ich habe diese Ursache nicht vermutet, weil die Tabellenzellen immer noch blau hervorgehoben wurden, als ob die Abgriffe durchkommen würden.
Alle guten Antworten, aber es gibt noch ein weiteres, auf das Sie achten sollten ...
(Insbesondere beim programmgesteuerten Erstellen eines UITableView)
Stellen Sie sicher, dass das tableView auf die Auswahl reagieren kann, indem Sie [tableView setAllowsSelection:YES];
setzen oder eine Zeile entfernen, in der NO
festgelegt ist.
Wenn das Problem mit UITapGestureRecognizer
auftritt, können Sie dies beheben:
im Code mit Objective-C
:
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(dismissKeyboard)];
[self.view addGestureRecognizer:tap];
[tap setCancelsTouchesInView:NO];
im Code mit Swift
:
let tap = UITapGestureRecognizer(target: self, action:Selector("dismissKeyboard"))
view.addGestureRecognizer(tap)
tap.cancelsTouchesInView = false
Ich bin in dieser Situation auf zwei Dinge gestoßen.
Möglicherweise haben Sie vergessen, das UITableViewDelegate-Protokoll zu implementieren, oder es gibt keinen Delegierungsauslass zwischen Ihrer Klasse und Ihrer Tabellenansicht.
Möglicherweise befindet sich in Ihrer Zeile ein UIView, der als Ersthelfer dient und Ihre Klicks wegnimmt. Sagen Sie ein UIButton oder ähnliches.
Ich hatte das gleiche Problem. Und es war schwer zu finden. Aber irgendwo in meinem Code Stand Folgendes:
- (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath {
return nil;
}
Es muss return indexPath
sein, andernfalls wird -tableView:didSelectRowAtIndexPath:
nicht aufgerufen.
Wenn Sie einen GestureRecognizer über UITableView hinzugefügt haben, wird didSelectRowAtIndexPath
nicht aufgerufen.
Sie müssen daher die gestureRecognizer-Delegatenmethode verwenden, um Berührungen in bestimmten Ansichten zu vermeiden.
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
if ([touch.view isDescendantOfView:YourTable]) {
return NO;
}
return YES;
}
Ich bin auf ein Problem gestoßen, bei dem ich nach Monaten, in denen ich nicht auf meinen Code geschaut hatte, vergessen hatte, dass ich die folgende Methode implementiert habe, aufgrund einiger nicht notwendiger Anforderungen
- (BOOL)tableView:(UITableView *)tableView shouldHighlightRowAtIndexPath:(NSIndexPath *)indexPath{
return NO;
}
Es sollte JA für eine Zeile zurückgegeben werden, um es auszuwählen.
Ich hatte das gleiche Problem,
Der Grund war die Verwendung von UITapGestureRecognizer
. Ich wollte, dass die Tastatur verworfen wird, wenn ich irgendwo anders angetippt habe. Mir wurde klar, dass dies alle Tipp-Aktionen überschreibt. Deshalb wurde die Funktion didSelectRowAtIndexPath
nicht aufgerufen.
Wenn ich die mit UITapGestureRecognizer
verknüpften Zeilen kommentiere, funktioniert es. Außerdem können Sie in der Funktion von UITapGestureRecognizer selector
prüfen, ob es sich bei dem getippten Wert um UITableViewCell
handelt oder nicht.
Falls Sie das gleiche Problem wie ich haben: Diese Methode wird anscheinend nicht aufgerufen, wenn sich Ihre tableView im Bearbeitungsmodus befindet. Sie müssen die Einstellung allowSelectionDuringEditing auf true setzen.
Über diese Frage: Beim Bearbeiten ruft "UITableView" nicht didSelectRowAtIndexPath auf?
Ich hatte eine UITapGestureRecognizer
in meine Tabellenansicht eingefügt, um die Tastatur zu schließen, wodurch der Aufruf von didSelectRowAtIndexPath:
verhindert wurde. Hoffe es hilft jemandem.
Denken Sie daran, die Datenquelle und den Delegaten in der viewDidLoad-Methode wie folgt festzulegen:
[self.tableView setDelegate:self];
[self.tableView setDataSource:self];
Auch wenn eine andere Antwort akzeptiert wurde, füge ich ein weiteres mögliches Problem und eine Lösung für Leute hinzu, die dieses Problem beobachten:
Wenn Sie die automatische Referenzzählung (Automatic Reference Counting, ARC) aktiviert haben, stellen Sie möglicherweise fest, dass selbst nach Zuweisung Ihres Controllers als Delegat der Ansicht die Meldungen der Ansicht an den Controller nicht empfangen werden, da ARC den Controller löscht. Anscheinend zählt der Delegate-Zeiger der UITableView nicht als Referenz für den ARC. Wenn dies der einzige Verweis darauf ist, wird der Controller als Dealloc deklariert. Sie können überprüfen, ob dies geschieht, indem Sie die Dealloc-Methode auf der Steuerung implementieren und dort einen Haltepunkt oder einen NSLog-Aufruf festlegen.
Die Lösung besteht darin, den Controller an einem anderen Ort mit einem starken Bezug zu überwachen, bis Sie sicher sind, dass Sie ihn nicht mehr benötigen.
Mein Problem war keines der oben genannten. Und so lahm. Aber ich dachte, ich würde es hier aufführen, falls es jemandem hilft.
Ich habe eine tableViewController
, die mein "Basis" -Controller ist, und dann erstelle ich Unterklassen dieses Controllers. Ich schrieb meinen gesamten Code in der tableView:didSelectRowAtIndexPath
-Routine in der Klasse "base". Ganz zu vergessen, dass diese Routine standardmäßig auch in allen meinen Unterklassen erstellt wurde (wenn auch ohne Code, der irgendetwas getan hat). Wenn ich also meine App ausführte, lief die Unterklassenversion des Codes, tat nichts und machte mich traurig. Nachdem ich die Routine aus den Unterklassen entfernt hatte, benutzte sie natürlich die Routine der Klasse "Base", und ich bin im Geschäft.
Ich kenne. Lache nicht Aber vielleicht wird jemand die Stunde retten, die ich verloren habe ...
Ich gebe meine 2 Cent dazu.
Ich hatte eine benutzerdefinierte UITableViewCell und es gab eine Schaltfläche, die die gesamte Zelle abdeckte. Wenn also die Berührung erfolgte, wurde die Schaltfläche ausgewählt und nicht die Zelle.
Entfernen Sie entweder die Schaltfläche oder in meinem Fall habe ich User Interation Enable für die Schaltfläche auf "false" gesetzt. Auf diese Weise wurde die Zelle ausgewählt.
Wenn Sie dies lesen, löst das Problem damit immer noch nicht.
Ich habe custom cell, wobei das Kontrollkästchen " User Interaction Enabled " deaktiviert war. Also schalte ich es einfach an. Viel Glück.
Ich hatte dies gerade und wie es mir in der Vergangenheit passiert ist, hat es nicht funktioniert, weil ich beim Versuch, die Methode hinzuzufügen, nicht auf die Autovervollständigung geachtet habe und am Ende tableView:didDeselectRowAtIndexPath
: statt tableView:didSelectRowAtIndexPath:
implementiere.
Ich weiß, ist alt und das Problem wurde gelöst, aber ein ähnliches Problem hatte ich, ich dachte, das Problem lag bei meiner benutzerdefinierten UITableViewCell, aber die Lösung war völlig anders - ich starte XCode neu :) und dann funktioniert es! fast wie Windows :)
Wenn sich Ihre Tabellenansicht im Bearbeitungsmodus befindet (zB [tableView setEditing:YES animated:NO];
), müssen Sie tableView.allowsSelectionDuringEditing = YES;
einstellen.
In meinem Fall bestand die Lösung darin, in der folgenden Funktion NEIN in JA zu ändern.
iOS 9+
- (BOOL)tableView:(UITableView *)tableView shouldHighlightRowAtIndexPath:(NSIndexPath *)indexPath
{
return YES;
}
Keine dieser Antworten funktionierte für mich. Nach etwa einer Stunde habe ich etwas sehr Schleichendes herausgefunden:
Ich habe eine Tabellenansicht in einer Zelle einer anderen Tabellenansicht. Ich entschied mich für eine einschließende Ansicht, die unter anderem die innere Tabellensicht enthält. Ich habe diese View contentView aufgerufen und sie im xib angeschlossen.
Es stellt sich heraus, dass UITableViewCell bereits eine contentView hat und seltsame Dinge damit macht. Das Problem wurde selbst behoben, als ich die Eigenschaft in mainContentView umbenannte und die Ansicht wieder mit dieser umbenannten Eigenschaft verbunden hatte.
In meinem Fall berechne ich dynamisch die Höhe des TableView
des SuperView
zum Ladezeitpunkt. Aufgrund einer Fehlkalkulation wurde der TableView
außerhalb des SuperView
positioniert. Das TableView
wurde gut gezeichnet, jedoch wurde jede Interaktion deaktiviert (und didSelectRowAtIndexPath
wurde nie aufgerufen). Sehr schwer zu erkennen, da es keinen visuellen Hinweis darauf gibt, dass TableView
nicht "zugänglich" ist.
Stellen Sie sicher, dass Sie tableView:didSelectRowAtIndexPath
und nicht tableView:didDeSelectRowAtIndexPath
implementiert haben.
Das hat mich mehr als ein paar Mal bekommen !!
Ein weiterer Fehler, den Sie hätten machen können (wie ich): Wenn Sie in der Zelle einen Abgleich festlegen, wird didSelectRowAtIndexPath
nicht aufgerufen. Sie sollten stattdessen Ihre Segmente auf dem View-Controller festlegen.
Ok, hier zu aktualisieren, als ich gerade auf dieses Problem gestoßen bin, und mein Problem war ein bisschen anders als hier.
Ich habe in IB nachgesehen und festgestellt, dass mein Delegat WAS festgelegt hatte, aber er wurde falsch auf VIEW anstelle von File's Owner gesetzt.
Hoffe das hilft jemandem
Achten Sie auf die UITableView
-Eigenschaften im Storyboard. In meinem Fall habe ich die Combox im Storyboard als "Auswahl: Einzelauswahl" ausgewählt, wodurch die Methode didSelectRowAtIndexPath
nicht ausgeführt wird.
Wenn Sie über eine benutzerdefinierte Zelle verfügen, müssen Sie UserInteractionEnabled in Xib (oder über Code) für die Zelle festlegen.
In meinem Fall hatte nur eine Zelle dieses Problem. Die Zelle enthielt den UITextView-Auslass im Readonly-Modus. Obwohl es vor dem Abklappvorgang gelesen wurde. Beim Tippen klappte die Tastatur. Es stellte sich heraus, dass die Interaktion noch deaktiviert werden musste.
cell.content.scrollEnabled = NO;
cell.content.editable = NO;
cell.content.userInteractionEnabled = NO;
cell.content.delegate = nil;
[cell.content resignFirstResponder];
Es gibt einige erstaunliche Hinweise und Antworten in diesem Beitrag (vielleicht eine der besten Diskussionen, die ich je gesehen habe!) Die Hinweise hier haben mir geholfen, herauszufinden, was mein Problem war, aber ich verbrachte immer noch viele Stunden damit, auf meiner Tastatur zu sabbern, um das zu entdecken Problem, das mit anderen Beiträgen vergleichbar war. Wie ich schließlich herausfand, dass es etwas anders war, wollte ich es mit anderen teilen, falls auch andere darauf stoßen.
Es stellte sich heraus, dass mein Problem darin bestand, dass eine Superklasse im Code eine "Fehleransicht" im Vollbildmodus hinzufügte, die nicht versteckt, sondern transparent war. Da es jedoch über der Tableview war und "Benutzeraktion" auf YES gesetzt war, wurden meine Berührungen mit der Tableview abgefangen.
Ich habe dies mit der coolen "Debug View Hierarchy" -Taste von Xcode diagnostiziert. Hier ist ein Screenshot mit Anmerkungen, die hoffentlich erklären, was ich getan habe und wie ich das Problem letztendlich diagnostiziert habe.
Im Code musste ich einfach tun:
errorMessageView.setUserInteractionEnabled = NO;
// or
errorMessageView.hidden = YES;
Wenn die Zelle, auf die Sie klicken, hervorgehoben wird, die Funktion jedoch immer noch nicht aufgerufen wird, überprüfen Sie die Signatur der Funktion. Es sollte so aussehen:
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
Dies war wahrscheinlich nur in meinem Fall, aber ich hatte einige Dateien aus einem Backup neu geladen, und die Dinge funktionierten nicht, einschließlich dieser. Nach einer vollständigen Reinigung (Product> Clean oder Shift + Command + K) hat es funktioniert. Wahrscheinlich wurde in einem vorkompilierten Header etwas versaut. Wahrscheinlich ist das nicht das Problem für Sie, aber es ist einen Versuch wert.
Prüfen Sie, ob Ihre viewController
folgende Methode hat:
- (BOOL) tableView:(UITableView *)tableView shouldHighlightRowAtIndexPath:(NSIndexPath *)indexPath {
return NO;
}
wenn Sie "NEIN" zurückgeben, wird didSelectRow nicht aufgerufen
In meinem Fall bestand das Problem darin, dass ich eine UITableViewCell
-Unterklasse hatte, und ich hatte die beiden folgenden Methoden implementiert: touchesBegan:withEvent:
& touchesEnded:withEvent
, um eine ausgefallene Animation bei Berührung zu handhaben .. __ Ich hatte vergessen, die [super touchesBegan:touches withEvent:event];
-Methode ad [super touchesEnded:touches withEvent:event];
hinzuzufügen Informieren Sie auch den Elternteil der Zelle über die Berührung.
Wenn Sie also den Code folgendermaßen ändern, wurde mein Problem gelöst:
-(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
}
Überprüfen Sie, ob -heightForRowAtIndexPath nicht 0 zurückgibt.
Ich hatte dieses Problem zeitweise. Wenn Sie eine Zelle berühren, wird sie manchmal ausgewählt. Manchmal würde es das Touch-Event nicht erhalten.
Ich verwende eine in ios8 eingeführte Funktion, die sich selbstgrößenoptimierende Zellen nennt. Ich bin auf diesen Blog-Beitrag gestoßen der darauf hinweist, dass:
Wenn die Tabellenansicht zum ersten Mal angezeigt wird, finden Sie möglicherweise einige Zellen sind nicht richtig dimensioniert. Wenn Sie jedoch in der Tabellenansicht blättern, wird das neue Zellen werden mit der richtigen Zeilenhöhe angezeigt. Um dieses Problem zu umgehen, ___. Sie können ein Neuladen erzwingen, nachdem die Ansicht angezeigt wird:
override func viewDidAppear(animated: Bool) {
tableView.reloadData()
}
Dies hat das Problem für mich behoben. Obwohl die Tabellensicht korrekt gerendert wurde, schien die Berührungshandhabung (speziell hitTest of UITableView) dem oben genannten Fehler zu unterliegen.
Ich hatte gerade dieses Problem, es trat jedoch nicht sofort auf; Nach der Auswahl einiger Zellen würden sie didSelectItemAtIndexPath
nicht mehr aufrufen. Mir wurde klar, dass das Problem darin bestand, dass die Sammlungsansicht allowsMultipleSelection
auf TRUE gesetzt hatte. Da Zellen nie abgewählt wurden, konnten zukünftige Aufrufe nicht mehr didSelectItemAtIndexPath
aufgerufen werden.
Eine andere verrückte Möglichkeit: Ich habe meine App auf einem iPhone 5S ausgeführt und habe Folgendes verwendet:
- (float)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
wie immer in der Vergangenheit.
Ich habe mir meine Compiler-Warnungen jedoch nicht genau genug angesehen. Ich sagte, ich sollte das über der Zeile ändern:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
64-Bit-Kompatibilität Faust schütteln
Seien Sie auf der Hut, falls Sie anfangen, Ihr Haar herauszuziehen.
Ich hatte einen Aufruf an cell.userInteractionEnabled, der in einem angepassten Tabellencode begraben war.
Blöd, sind doch die meisten Fehler nicht?
Ich habe alle vorherigen Antworten durchlaufen, aber mir hat keine geholfen. Nach einigem Ausprobieren fand ich eine andere Lösung. Ich hatte eine UIImageView, die die gesamte Zelle abdeckt (als Hintergrund). Standardmäßig ist bei einer UIImageView die Benutzerinteraktion deaktiviert. Durch die Aktivierung der Benutzerinteraktion der Imageviews wurde die Delegat-Methode -didSelectRowAtIndexPath: erneut aufgerufen.
cell.imgView.userInteractionEnabled = YES;
Ich hatte selbst dieses Problem. Ich hatte die Knochen der Ansicht in IB (nur eine Ansicht und eine Tabellenansicht) erstellt, und der Delegat wurde nicht festgelegt. Ich habe es mit dem Besitzer von File verbunden und es funktionierte wie ein Zauber. ::sparen::
Eine weitere mögliche Ursache scheint zu sein, dass die UITableView
in eine UIScrollView
eingebettet ist. Ich hatte dieses Problem heute, weil ich versehentlich eine Bildlaufansicht anstelle einer normalen Ansicht als Stammansicht meines Controllers hatte.
Ich kann nicht kommentieren, schreibe hier ... In meinem Fall hat didSelectRow
gearbeitet, aber nicht didDeselectRow
. Ich setze delegate
und dataSource
für tableView
und löste meinen Fall.
In meinem Fall bestand das Problem darin, die Methode als privat zu deklarieren.
Das hat nicht funktioniert:
private func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
Das hat funktioniert:
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
Stellen Sie sicher, dass Sie reloadData
im Hauptthread aufrufen. Wenn Sie diese Methode über eine asynchrone Methode aufrufen (z. B. eine Netzwerkanforderung), reagiert die Tabellensicht möglicherweise nicht richtig (in einigen Fällen kann die App sogar abstürzen).
Verwenden Sie einen Haupt-Thread-Codeblock, um den Aufruf reloadData
auszuführen, wenn der Aufruf in einem anderen Methodenblock ausgeführt wird (dessen Sie sich nicht sicher sind):
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
[tableView reloadData];
}];
Ich habe gerade einen anderen Weg gefunden, um nicht Ihre didSelect
-Methode aufzurufen. Irgendwann schlug XCode vor, während eines Fehlers in der Funkdeklaration selbst, @nonobjc zu meiner Methode hinzuzufügen:
@nonobjc func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
Dies wird weiterhin ohne Beanstandung kompiliert, aber Sie werden von den UI-Aktionen niemals aufgerufen.
"Das sind meine zwei Cent und ich will mein Wechselgeld zurück"
@interface ExampleViewController () <UITableViewDelegate, UITableViewDataSource>
hinzufügen
Machen Sie eine Delegation im Storyboard
Code hinzufügen
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
NSString *cellText = cell.textLabel.text;
}
Bitte suchen Sie nach UITapGestureRecognizer. In meinem Fall wurde eine Tapgesture für die Ansicht hinzugefügt, in der die Tabellenansicht platziert wurde, wodurch die Benutzerinteraktion von UITableview wie bei didselect beeinträchtigt wird. Nach dem Deaktivieren von tapgesture für die Ansicht wurde didselect delegate ausgelöst.
Ich habe alle Antworten gelesen und bin mit ihnen einverstanden. Aber in meinem Fall ist es ganz anders. Ich hatte einen neuen segue
namen__ für meinen detailViewController
namen__, der direkt mit meinem tableCell
namen__ in StoryBoard verknüpft war, was dies verursachte. Also musste ich diesen Abschnitt aus meiner Zelle entfernen und ihn mit dem Namen der UITableViewController
selbst verknüpfen. Nun, indem Sie den folgenden Code schreiben, funktioniert es,
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
// Do any operation
performSegue(withIdentifier: "DetailSegue", sender: self)
}
Hoffe, diese Lösung hilft jemandem da draußen!
sie müssen sicherstellen, dass diese Auswahl eine Einzelauswahl ist und dass während der Bearbeitung keine Auswahl getroffen werden darf und Sie die Einstellung in den Eigenschaften von uttableviewcell ändern, auch wenn Sie sie in der Tabellenansicht bearbeiten. Der Zellenstil muss benutzerdefiniert und der Bezeichner muss Rid und der Abschnitt none sein
Ich bin mir nicht sicher, ob jemand so weit scrollen kann, um diese Antwort zu sehen, aber da dies die beliebteste Frage zu diesem Thema ist und die Antwort nicht da war, füge ich sie hinzu:
Ab Xcode 9/Swift 4 sollten alle Objective-C-Methoden mit @objc
gekennzeichnet sein. Der Compiler erkennt vernünftigerweise, wo er angewendet werden soll, er ermittelt jedoch nicht die Vererbung. Zum Beispiel:
class Delegate: NSObject, UITableViewDelegate {
}
class SuperDelegate: Delegate {
override func tableView(_ tableView: UITableView, willSelectRowAt indexPath: IndexPath) -> IndexPath? { return indexPath }
}
Dadurch werden keine Warnungen, Abstürze oder Build-Fehler generiert. Ihre Leitung wird jedoch erst dann angerufen, wenn Sie @objc
hinzufügen:
@objc class SuperDelegate: Delegate {
override func tableView(_ tableView: UITableView, willSelectRowAt indexPath: IndexPath) -> IndexPath? { return indexPath }
}
Ich hatte das Problem, dass die Kontrolle nach dem Anwenden des Haltepunkts nicht zur Auswahl der Zeile führte. Problem war in Sicht. Ich habe die Tab-Geste aus der Ansicht entfernt. dann hat es gut funktioniert
in meinem Fall habe ich einen kleinen Fehler gemacht:
tableView.isUserInteractionEnabled = false
es sollte sein:
tableView.isUserInteractionEnabled = true