2013-03-29 13 views
57

Wie bekomme ich von einer Zelle ihre indexPath in einer UITableView?Wie bekomme ich UITableViewCell indexPath von der Zelle?

Ich habe rund um Stack-Überlauf und Google gesucht, aber alle Informationen sind auf der anderen Seite herum. Gibt es eine Möglichkeit, auf die superView/UITableView zuzugreifen und dann nach der Zelle zu suchen?

Weitere Informationen über den Kontext: Es gibt zwei Klassen, die ich habe, ist man genannt Cue und ein CueTableCell genannt wird (die eine Unterklasse von UITableViewCell ist) CueTableCell ist die visuelle Darstellung von Cue (beide Klassen haben Zeiger zueinander). Objekte sind in einer verknüpften Liste und wenn der Benutzer einen bestimmten Befehl ausführt, muss die visuelle Darstellung (CueTableCell) des nächsten Cue ausgewählt werden. So ruft die Cue Klasse die select Methode auf der nächsten Cue in der Liste, die die UITableView aus der cell abruft und ruft selectRowAtIndexPath:animated:scrollPosition:, für die es die indexPath der UITableViewCell benötigt.

+2

Genau wie Ihre andere [Frage] (http://stackoverflow.com/questions/15711645/how-to-get-guidableview-from-guidableviewcell) auf die "UITableView" von einer Zelle - warum?Dies scheint wie ein Code-Geruch einer schlechten Designentscheidung zu sein - es gibt nicht viele legitime Anwendungsfälle für eine Zelle, um zu wissen, ob sie indexPath ist oder ob sie auf dem Bildschirm ist oder nicht. –

+0

Ich stimme dem Kommentar von Paul.s zu. Sie sollten angeben, warum Sie dies tun möchten, denn was Sie versuchen, ist wahrscheinlich eine schlechte Idee. – rdelmar

+0

@ Paul.s Ich habe das Design meines Programms in der Frage veröffentlicht. Es kann eine schlechte Programmierpraxis sein, in diesem Fall, wenn Sie eine Alternative vorschlagen könnten, wäre das sehr hilfreich. Ich bin sehr neu in Kakao und relativ neu in der Programmierung im Allgemeinen. –

Antwort

120
NSIndexPath *indexPath = [self.tableView indexPathForCell:cell]; 

Es hilft, die documentation lesen, auch wenn dies von einigen als kontrovers angesehen (siehe Kommentare unten).

Die Zelle weiß nicht, was ihr Indexpfad ist. Der Controller sollte einen beliebigen Code enthalten, der UI-Elemente basierend auf dem Datenmodell bearbeitet oder Daten basierend auf UI-Interaktionen ändert. (Siehe MVC.)

+30

Es hilft, wenn Sie die Frage lesen. Dies stammt von einer UITableViewCell, die keine Eigenschaft "tableView" hat (und bei allen Konten nicht). – voidref

+10

@voidref Es hilft auch, über die Frage nachzudenken ;-). Die Zelle weiß nicht, was ihr Indexpfad ist. Also sollte dieser Code in der Steuerung sein. Hintergrundinformationen zu MVC finden Sie unter [Cocoa Kernkompetenzen] (https://developer.apple.com/library/ios/#documentation/General/Conceptual/DevPedia-CocoaCore/MVC.html). – Mundi

+0

Fair genug, aber dann sollte deine ursprüngliche Antwort das erklärt haben. – shim

23

mit diesem Versuchen von Ihrem UITableViewCell:

NSIndexPath *indexPath = [(UITableView *)self.superview indexPathForCell: self]; 

EDIT: Es scheint, dies nicht auf iOS 8.1.2 funktioniert und weiter. Danke an Chris Prince für den Hinweis.

+7

Mit iOS 8.1.2 hat der Superview einer Tabellenansichtszelle den Typ UITableViewWrapperView. Der Superview davon ist vom Typ Tabellenansicht. Aber ich denke, wir treten auf gefährlichem Boden hier ... –

+1

Alles zurück zum geht „Die Zelle hat nichts zu wissen, was seinen Index Weg ist.“ Streit. Zugriff auf Superview ist fast immer ein Hack und es ist nicht überraschend, dass es nach einer Weile nicht funktioniert. – fatuhoku

+0

Völlig richtig fatuhoku, es ist nicht die Frage der Zelle des Indexpfads wissen –

3

Die Antwort auf diese Frage hat mir tatsächlich sehr geholfen.

benutzte ich NSIndexPath *indexPath = [self.tableView indexPathForCell:sender];

Die sender in meinem Fall war ein UITableViewCell und stammt aus dem prepareForSegue Verfahren.

habe ich das, weil ich nicht eine TableViewController hatte, aber ich hatte UITableView property outlet

Ich brauchte den Titel des Cell, um herauszufinden, und damit die indexPath davon wissen musste.

Hoffe das hilft jedem!

7

diejenigen ansprechen, die sagen: „Das ist eine schlechte Idee“, in meinem Fall, denn das ist mein Bedürfnis ist, dass ich eine Taste auf meiner UITableViewCell haben, die, wenn sie gedrückt wird, ein Übergang in eine andere Ansicht ist. Da dies keine Auswahl für die Zelle selbst ist, funktioniert [self.tableView indexPathForSelectedRow] nicht.

Dies lässt mich zwei Möglichkeiten:

  1. Bewahren Sie das Objekt, das ich brauche, sich in der Tabellenzelle in die Ansicht zu übergeben. Während dies funktionieren würde, würde es den Punkt von mir mit einer NSFetchedResultsController besiegen, weil ich nicht möchte alle Objekte im Speicher zu speichern, vor allem, wenn die Tabelle lang ist.
  2. Rufen Sie das Element vom Abrufcontroller mithilfe des Indexpfads ab. Ja, es scheint hässlich, dass ich die NSIndexPath durch einen Hack herausfinden muss, aber es ist letztlich weniger teuer als Objekte im Speicher zu speichern.

indexPathForCell: ist die richtige Methode zu verwenden, aber hier ist, wie ich es tun würde (dieser Code angenommen wird, in einer Unterklasse von UITableViewCell umgesetzt werden:

// 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; 
} 

PS Mein richtigen Code macht den Zugriff alles aus der Tabellenansicht, aber ich gebe ein Beispiel, warum jemand

direkt so etwas wie dies in der Tabellenzelle tun wollen könnte
10
  1. eine schwache wie H-Datei Tableview Eigenschaft in Zelle Put.

    @property (weak,nonatomic)UITableView *tableView;

  2. die Eigenschaft in cellForRowAtIndex Methode Weisen wie:

    cell.tableView = tableView;

  3. , wo Sie die indexPath der Zelle Jetzt müssen:

    NSIndexPath *indexPath = [cell.tableView indexPathForCell:cell];

+0

Das funktioniert, weil wir nur einen Zeiger auf die Tableview speichert selbst aber indexPathForCell zuverlässig ist? Ich dachte, dies bietet nur IndexPath von sichtbaren Zellen nicht? – jcpennypincher

0

Versuchen Sie, mit dieser von Ihrem UITableViewCell:

NSIndexPath *indexPath = [(UITableView *)self.superview.superview indexPathForCell:self]; 
+0

funktioniert nicht, da ios 8 –

1

dies versuchen (es funktioniert nur, wenn der Tableview nur einen Abschnitt hat und alle Zellen hat gleiche Höhe):

//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; 
10

Sie können diese einfache Spitze versuchen :

auf UITableViewCell Klasse:

@property NSInteger myCellIndex; //or add directly your indexPath 

und auf cellForRowAtIndexPath Methode:

... 
[cell setMyCellIndex : indexPath.row] 

jetzt können Sie Ihr Handy Index überall abrufen

+2

Sie müssen sich daran erinnern, diese Informationen manuell zu aktualisieren, nachdem Nachbestellung oder Zellen zu löschen. – konrad

5

Für schnelle

let indexPath :NSIndexPath = (self.superview.superview as! UITableView).indexPathForCell(self)! 
0

Auf iOS 11.0, können Sie UITableView.indexPathForRow(at point: CGPoint) -> IndexPath?:

if let indexPath = tableView.indexPathForRow(at: cell.center) { 
    tableView.selectRow 
    (at: indexPath, animated: true, scrollPosition: .middle) 
} 

Er ruft den Mittelpunkt der Zelle ab, und dann gibt die TabelleView den indexPath-Korrespondenten zurück bis zu diesem Punkt.

Verwandte Themen