Wie bekomme ich aus einer Zelle seine indexPath
in eine UITableView
?
Ich habe nach Stapelüberlauf und Google gesucht, aber alle Informationen sind umgekehrt. Gibt es eine Möglichkeit, auf superView
/UITableView
zuzugreifen und dann nach der Zelle zu suchen?
Weitere Informationen zum Kontext: Es gibt zwei Klassen, die ich besitze, eine heißt Cue
und eine CueTableCell
(welche eine Unterklasse von UITableViewCell
ist). CueTableCell
ist die visuelle Darstellung von Cue
(beide Klassen haben Zeiger auf einander). Cue
-Objekte befinden sich in einer verknüpften Liste. Wenn der Benutzer einen bestimmten Befehl ausführt, muss die visuelle Darstellung (CueTableCell
) des nächsten Cue
-Objekts ausgewählt werden. Daher ruft die Cue
-Klasse die select
-Methode für das nächste Cue
in der Liste auf, die UITableView
von der cell
abruft und ihren selectRowAtIndexPath:animated:scrollPosition:
aufruft, für den es die indexPath
der UITableViewCell
benötigt.
NSIndexPath *indexPath = [self.tableView indexPathForCell:cell];
Es hilft beim Lesen der Dokumentation , auch wenn dies von manchen als kontrovers angesehen wird (siehe Kommentare unten).
Die Zelle hat kein Geschäft, das den Indexpfad kennt. Der controller sollte jeden Code enthalten, der Benutzeroberflächenelemente basierend auf dem Datenmodell oder Daten basierend auf Benutzeroberflächeninteraktionen bearbeitet. (Siehe MVC .)
Versuchen Sie es mit Ihrer UITableViewCell:
NSIndexPath *indexPath = [(UITableView *)self.superview indexPathForCell: self];
BEARBEITEN: Anscheinend funktioniert das nicht unter iOS 8.1.2 und weiter. Vielen Dank an Chris Prince für das Zeigen.
Sie können diesen einfachen Tipp ausprobieren:
in deiner UITableViewCell
Klasse:
@property NSInteger myCellIndex; //or add directly your indexPath
und auf deiner cellForRowAtIndexPath
Methode:
...
[cell setMyCellIndex : indexPath.row]
jetzt können Sie Ihren Zellindex überall abrufen
Fügen Sie eine schwache tableView-Eigenschaft in die .h-Datei der Zelle ein:
@property (weak,nonatomic)UITableView *tableView;
Weisen Sie die Eigenschaft in der cellForRowAtIndex-Methode wie folgt zu:
cell.tableView = tableView;
Jetzt, wo immer Sie den indexPath der Zelle brauchen:
NSIndexPath *indexPath = [cell.tableView indexPathForCell:cell];
Um sich an diejenigen zu wenden, die "Dies ist eine schlechte Idee"ansprechen, in meinem Fall ist es für mich ein Bedürfnis, dass ich einen Button auf meiner UITableViewCell
habe, der beim Drücken zu einer anderen Ansicht führt. Da dies keine Auswahl in der Zelle selbst ist, funktioniert [self.tableView indexPathForSelectedRow]
nicht.
Dies lässt mir zwei Möglichkeiten:
NSFetchedResultsController
habe, zunichte machen, da ich nicht alle Objekte im Speicher ablegen möchte, insbesondere wenn die Tabelle lang ist.NSIndexPath
durch einen Hack herausfinden muss, aber es ist letztendlich weniger teuer als das Speichern von Objekten im Speicher.indexPathForCell:
ist die richtige zu verwendende Methode, aber so würde ich es tun (dieser Code soll in einer Unterklasse von UITableViewCell
implementiert sein:
// uses the indexPathForCell to return the indexPath for itself
- (NSIndexPath *)getIndexPath {
return [[self getTableView] indexPathForCell:self];
}
// retrieve the table view from self
- (UITableView *)getTableView {
// get the superview of this class, note the camel-case V to differentiate
// from the class' superview property.
UIView *superView = self.superview;
/*
check to see that *superView != nil* (if it is then we've walked up the
entire chain of views without finding a UITableView object) and whether
the superView is a UITableView.
*/
while (superView && ![superView isKindOfClass:[UITableView class]]) {
superView = superView.superview;
}
// if superView != nil, then it means we found the UITableView that contains
// the cell.
if (superView) {
// cast the object and return
return (UITableView *)superView;
}
// we did not find any UITableView
return nil;
}
P.S. Mein eigentlicher Code greift auf das alles von der Tabellensicht aus zu, aber ich gebe ein Beispiel dafür, warum jemand etwas in der Tabellenzelle direkt machen möchte.
Für Swift
let indexPath :NSIndexPath = (self.superview.superview as! UITableView).indexPathForCell(self)!
Die Antwort auf diese Frage hat mir tatsächlich sehr geholfen.
Ich habe NSIndexPath *indexPath = [self.tableView indexPathForCell:sender];
verwendet
Die sender
war in meinem Fall eine UITableViewCell
und stammt von der prepareForSegue
-Methode.
Ich habe dies verwendet, weil ich nicht eine TableViewController
hatte, aber ich hatte UITableView property outlet
Ich musste den Titel der Cell
herausfinden und musste daher den indexPath davon kennen.
Ich hoffe, das hilft jedem!
Unter iOS 11.0 können Sie UITableView.indexPathForRow(at point: CGPoint) -> IndexPath?
verwenden:
if let indexPath = tableView.indexPathForRow(at: cell.center) {
tableView.selectRow
(at: indexPath, animated: true, scrollPosition: .middle)
}
Es holt den Mittelpunkt der Zelle und gibt dann den indexPath zurück, der diesem Punkt entspricht.
probiere dies (es funktioniert nur, wenn die tableView nur einen Abschnitt hat und alle Zellen gleich hoch sind):
//get current cell rectangle relative to its superview
CGRect r = [self convertRect:self.frame toView:self.superview];
//get cell index
int index = r.Origin.y / r.size.height;
Swift 4.x
Um Zugang zu meinem Handy zu ermöglichen, habe ich so etwas gemacht:
Ich habe eine Erweiterung der UIView:
extension UIView {
var parentViewController: UIViewController? {
var parentResponder: UIResponder? = self
while parentResponder != nil {
parentResponder = parentResponder!.next
if let viewController = parentResponder as? UIViewController {
return viewController
}
}
return nil
}
}
Und dann .. in meiner Zelle Klasse:
class SomeCell: UITableViewCell {
func someMethod() {
if let myViewController = self.parentViewController as? CarteleraTableViewController {
let indexPath : IndexPath = (myViewController.tableView).indexPath(for: self)!
print(indexPath)
}
}
}
Das ist alles, was mich ausmacht.
Freundliche Grüße.
Versuchen Sie es mit Ihrer UITableViewCell:
NSIndexPath *indexPath = [(UITableView *)self.superview.superview indexPathForCell:self];