Ich habe eine Tabellenansicht mit Schaltflächen und möchte die indexpath.row verwenden, wenn eine davon angetippt wird. Dies ist, was ich derzeit habe, aber es ist immer 0
var point = Int()
func buttonPressed(sender: AnyObject) {
let pointInTable: CGPoint = sender.convertPoint(sender.bounds.origin, toView: self.tableView)
let cellIndexPath = self.tableView.indexPathForRowAtPoint(pointInTable)
println(cellIndexPath)
point = cellIndexPath!.row
println(point)
}
swift
button
touch
nsindexpath
Vincent
quelle
quelle
Antworten:
Giorashc hatte es fast mit seiner Antwort, aber er übersah die Tatsache, dass Zellen eine zusätzliche
contentView
Schicht haben. Wir müssen also eine Schicht tiefer gehen:Dies liegt daran, dass innerhalb der Ansichtshierarchie eine Tabellenansicht Zellen als Unteransichten hat, die anschließend ihre eigenen "Inhaltsansichten" haben. Aus diesem Grund müssen Sie die Übersicht dieser Inhaltsansicht abrufen, um die Zelle selbst abzurufen. Wenn Ihre Schaltfläche in einer Unteransicht und nicht direkt in der Inhaltsansicht der Zelle enthalten ist, müssen Sie daher viele Ebenen tiefer gehen, um darauf zuzugreifen.
Das Obige ist ein solcher Ansatz, aber nicht unbedingt der beste. Es ist zwar funktionsfähig, setzt jedoch Details zu einem voraus
UITableViewCell
, die Apple nie unbedingt dokumentiert hat, z. B. die Ansichtshierarchie. Dies könnte in Zukunft geändert werden, und der obige Code kann sich daher möglicherweise unvorhersehbar verhalten.Aus Gründen der Langlebigkeit und Zuverlässigkeit empfehle ich daher einen anderen Ansatz. In diesem Thread sind viele Alternativen aufgeführt, und ich empfehle Ihnen, diese zu lesen, aber mein persönlicher Favorit lautet wie folgt:
Halten Sie eine Eigenschaft eines Abschlusses für Ihre Zellenklasse gedrückt, und lassen Sie die Aktionsmethode der Schaltfläche dies aufrufen.
Wenn Sie dann Ihre Zelle in erstellen
cellForRowAtIndexPath
, können Sie Ihrem Abschluss einen Wert zuweisen.Wenn Sie Ihren Handlercode hierher verschieben, können Sie das bereits vorhandene
indexPath
Argument nutzen. Dies ist ein viel sichererer Ansatz als der oben aufgeführte, da er nicht auf undokumentierten Merkmalen beruht.quelle
Mein Ansatz für diese Art von Problem besteht darin, ein Delegatenprotokoll zwischen der Zelle und der Tabellenansicht zu verwenden. Auf diese Weise können Sie den Schaltflächenhandler in der Unterklasse der Zelle belassen, wodurch Sie den Handler für Ausbesserungsaktionen der Prototypzelle in Interface Builder zuweisen können, während die Logik der Schaltflächenhandler im Ansichtscontroller erhalten bleibt.
Außerdem wird der potenziell fragile Ansatz des Navigierens in der Ansichtshierarchie oder der Verwendung der
tag
Eigenschaft vermieden , der Probleme beim Ändern von Zellindizes (aufgrund des Einfügens, Löschens oder Neuordnens) aufweist.CellSubclass.swift
ViewController.swift
quelle
buttonTapped
ist die Delegatenfunktion und befindet sich im View Controller. In meinem BeispielsomeButtonTapped
ist die Aktionsmethode in der Zelle@IBAction func someButtonTapped(sender: UIButton) { self.delegate?.buttonTapped(self) }
AKTUALISIEREN : Abrufen des Indexpfads der Zelle, die die Schaltfläche enthält (sowohl Abschnitt als auch Zeile):
Verwenden der Tastenposition
Innerhalb Ihrer
buttonTapped
Methode können Sie die Position der Schaltfläche erfassen, sie in eine Koordinate in der Tabellenansicht konvertieren und dann den Indexpfad der Zeile an dieser Koordinate abrufen.ANMERKUNG : Manchmal kann es vorkommen, dass Sie bei Verwendung der Funktion auf einen Randfall stoßen
view.convert(CGPointZero, to:self.tableView)
,nil
um an einem Punkt nach einer Zeile zu suchen, obwohl dort eine tableView-Zelle vorhanden ist. Um dies zu beheben, versuchen Sie, eine echte Koordinate zu übergeben, die leicht vom Ursprung versetzt ist, z.Vorherige Antwort: Verwenden der Tag-Eigenschaft (gibt nur die Zeile zurück)
Anstatt in die Überwachungsbäume zu klettern, um einen Zeiger auf die Zelle zu erhalten, in der sich der UIButton befindet, gibt es eine sicherere, wiederholbarere Technik, bei der die von Antonio oben erwähnte Eigenschaft button.tag verwendet wird, die in beschrieben ist dieser Antwort gezeigte :
In
cellForRowAtIndexPath:
legen Sie die Tag-Eigenschaft fest:Anschließend
buttonClicked:
verweisen Sie in der Funktion auf dieses Tag, um die Zeile des Indexpfads abzurufen, in der sich die Schaltfläche befindet:Ich bevorzuge diese Methode, da ich festgestellt habe, dass das Schwingen in den Übersichtsbäumen eine riskante Möglichkeit sein kann, eine App zu entwerfen. Auch für Ziel-C habe ich diese Technik in der Vergangenheit verwendet und war mit dem Ergebnis zufrieden.
quelle
indexPath.section
zusätzlich zuindexPath.row
(ohne Zurücksetzen der Tag-Eigenschaft alsindexPath.section
) erhalten möchten , könnencellForRowAtIndexPath:
Sie in einfach das Tag in ändernbutton.tag = indexPath
und dann in derbuttonClicked:
Funktion mitsender.tag.row
und auf beide zugreifensender.tag.section
.Verwenden Sie eine Erweiterung von UITableView, um die Zelle für eine beliebige Ansicht abzurufen:
Die Antwort von @ Paulw11, einen benutzerdefinierten Zelltyp mit einer Delegate-Eigenschaft einzurichten, die Nachrichten an die Tabellenansicht sendet, ist ein guter Weg, erfordert jedoch einen gewissen Arbeitsaufwand für die Einrichtung.
Ich halte es für eine schlechte Idee, in der Ansichtshierarchie der Tabellenansichtszelle nach der Zelle zu suchen. Es ist zerbrechlich - wenn Sie Ihre Schaltfläche später zu Layoutzwecken in eine Ansicht einfügen, wird dieser Code wahrscheinlich beschädigt.
Die Verwendung von Ansichts-Tags ist ebenfalls fragil. Sie müssen daran denken, die Tags beim Erstellen der Zelle einzurichten. Wenn Sie diesen Ansatz in einem Ansichts-Controller verwenden, der Ansichts-Tags für einen anderen Zweck verwendet, können doppelte Tag-Nummern vorhanden sein und Ihr Code funktioniert möglicherweise nicht wie erwartet.
Ich habe eine Erweiterung für UITableView erstellt, mit der Sie den Indexpfad für jede Ansicht abrufen können, die in einer Tabellenansichtszelle enthalten ist. Es
Optional
wird ein Wert zurückgegeben, der gleich Null ist, wenn die übergebene Ansicht tatsächlich nicht in eine Tabellenansichtszelle fällt. Unten finden Sie die gesamte Erweiterungsquelldatei. Sie können diese Datei einfach in Ihr ProjektindexPathForView(_:)
einfügen und dann mit der enthaltenen Methode den Indexpfad finden, der eine beliebige Ansicht enthält.Um es zu verwenden, können Sie einfach die Methode in der IBAction für eine Schaltfläche aufrufen, die in einer Zelle enthalten ist:
(Notiere dass der
indexPathForView(_:)
Funktion nur funktioniert, wenn das übergebene Ansichtsobjekt in einer Zelle enthalten ist, die derzeit auf dem Bildschirm angezeigt wird. Dies ist sinnvoll, da eine Ansicht, die nicht auf dem Bildschirm angezeigt wird, nicht zu einem bestimmten Indexpfad gehört einem anderen Indexpfad zugewiesen werden, wenn die enthaltene Zelle recycelt wird.)BEARBEITEN:
Sie können ein funktionierendes Demo-Projekt, das die obige Erweiterung verwendet, von Github herunterladen : TableViewExtension.git
quelle
Zum
Swift2.1
Ich habe einen Weg gefunden, es zu tun, hoffentlich hilft es.
quelle
Sie haben eine Schaltfläche (myButton) oder eine andere Ansicht in der Zelle. Weisen Sie das Tag in cellForRowAt wie folgt zu
Jetzt in dir tapFunction oder eine andere. Holen Sie es so heraus und speichern Sie es in einer lokalen Variablen.
Danach können Sie diese currentCellNumber an einer beliebigen Stelle verwenden, um die indexPath.row der ausgewählten Schaltfläche abzurufen.
Genießen!
quelle
Verwenden Sie in Swift 4 einfach Folgendes:
quelle
tableView
es sich um eine Ausgangsvariable handelt, auf die verwiesen werden muss, bevor diese Antwort funktioniert.Sehr einfach, Indexpfad schnell zu bekommen 4, 5
So erhalten Sie IndexPath Inside Btn Klicken Sie auf:
quelle
Da der Absender des Ereignishandlers die Schaltfläche selbst ist, würde ich die
tag
Eigenschaft der Schaltfläche verwenden , um den in initialisierten Index zu speicherncellForRowAtIndexPath
.Aber mit etwas mehr Arbeit würde ich das ganz anders machen. Wenn Sie eine benutzerdefinierte Zelle verwenden, würde ich das Problem folgendermaßen angehen:
cellForRowAtIndexPath
quelle
Nachdem ich Paulw11s Vorschlag gesehen hatte, einen Rückruf für Delegierte zu verwenden, wollte ich ihn etwas näher erläutern / einen anderen, ähnlichen Vorschlag vorbringen. Wenn Sie das Delegatenmuster nicht verwenden möchten, können Sie Verschlüsse schnell wie folgt verwenden:
Ihre Zellklasse:
Ihre
cellForRowAtIndexPath
Methode:quelle
Ich habe eine sehr einfache Möglichkeit gefunden, eine Zelle in tableView und collectionView mithilfe einer Model-Klasse zu verwalten, und dies funktioniert genauso perfekt.
Es gibt in der Tat einen viel besseren Weg, dies jetzt zu handhaben. Dies funktioniert für die Verwaltung von Zelle und Wert.
Hier ist meine Ausgabe (Screenshot).
RNCheckedModel
und schreiben Sie den Code wie folgt.quelle
Ich habe die convertPoint-Methode verwendet, um einen Punkt aus der Tabellenansicht abzurufen und diesen Punkt an die indexPathForRowAtPoint-Methode zu übergeben, um indexPath abzurufen
quelle
Versuchen Sie, mit #selector die IBaction.In dem cellforrowatindexpath aufzurufen
Auf diese Weise können Sie auf den Indexpfad innerhalb der Methode editButtonPressed zugreifen
quelle
In meinem Fall habe ich mehrere Abschnitte und sowohl der Abschnitts- als auch der Zeilenindex sind von entscheidender Bedeutung. In einem solchen Fall habe ich gerade eine Eigenschaft auf UIButton erstellt, für die ich den Zellenindexpfad wie folgt festgelegt habe:
Setzen Sie dann die Eigenschaft in cellForRowAt wie folgt:
Dann können Sie in handleTapAction den indexPath wie folgt abrufen:
quelle
Swift 4 und 5
Methode 1 unter Verwendung des Protokolldelegaten
Zum Beispiel haben Sie einen
UITableViewCell
mit NamenMyCell
Erstellen Sie nun eine
protocol
Erstellen Sie im nächsten Schritt eine Erweiterung von
UITableView
In Ihrem
UIViewController
implementieren Sie das ProtokollMyCellDelegate
Methode 2 mit Verschlüssen
Im
UIViewController
quelle
In Swift 3. Auch Guard-Anweisungen verwendet, um eine lange Kette von Klammern zu vermeiden.
quelle
Manchmal befindet sich die Schaltfläche in einer anderen Ansicht von UITableViewCell. In diesem Fall gibt Aufsichtsübersicht möglicherweise nicht das Zellenobjekt an, und daher ist der Indexpfad Null.
In diesem Fall sollten wir die Übersicht so lange finden, bis wir das Zellenobjekt erhalten.
Funktion zum Abrufen des Zellenobjekts per Übersicht
Jetzt können wir indexPath beim Tippen auf die Schaltfläche wie unten erhalten
quelle
quelle