it-swarm.com.de

Wie erhält man UITableViewCell indexPath aus der Zelle?

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.

63
sinθ
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 .)

126
Mundi

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. 

25
Pepper

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

10
  1. Fügen Sie eine schwache tableView-Eigenschaft in die .h-Datei der Zelle ein:

    @property (weak,nonatomic)UITableView *tableView;

  2. Weisen Sie die Eigenschaft in der cellForRowAtIndex-Methode wie folgt zu:

    cell.tableView = tableView;

  3. Jetzt, wo immer Sie den indexPath der Zelle brauchen:

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

10
Chanchal Raj

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:

  1. Speichern Sie das Objekt, das ich in die Ansicht übergeben muss, in der Tabellenzelle. Während dies funktionieren würde, würde dies den Punkt, an dem ich eine NSFetchedResultsController habe, zunichte machen, da ich nicht alle Objekte im Speicher ablegen möchte, insbesondere wenn die Tabelle lang ist.
  2. Rufen Sie das Element mithilfe des Indexpfads vom Abrufcontroller ab. Ja, es scheint hässlich, dass ich 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.

9
mikeho

Für Swift 

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

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!

4
Cescy

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. 

2
banan3'14

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;
1
m.eldehairy

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.

0
LagMaster

Versuchen Sie es mit Ihrer UITableViewCell:

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