Comment puis-je, à partir d'une cellule, obtenir sa indexPath
dans une UITableView
?
J'ai effectué des recherches sur le débordement de pile et sur Google, mais toutes les informations sont inversées. Existe-t-il un moyen d'accéder à la variable superView
/UITableView
, puis de rechercher la cellule?
Plus d'informations sur le contexte: j'ai deux classes, l'une s'appelle Cue
et l'autre CueTableCell
(qui est une sous-classe de UITableViewCell
) CueTableCell
est la représentation visuelle de Cue
(les deux classes ont des pointeurs entre elles). Les objets Cue
sont dans une liste chaînée et lorsque l'utilisateur exécute une certaine commande, la représentation visuelle (la CueTableCell
) de la prochaine Cue
doit être sélectionnée. Ainsi, la classe Cue
appelle la méthode select
sur la prochaine Cue
de la liste, qui extrait la UITableView
de la cell
et appelle sa selectRowAtIndexPath:animated:scrollPosition:
, pour laquelle elle a besoin de la indexPath
de la UITableViewCell
.
NSIndexPath *indexPath = [self.tableView indexPathForCell:cell];
Cela facilite la lecture de la documentation , même si cela est considéré par certains comme controversé (voir les commentaires ci-dessous).
La cellule n'a pas d'activité sachant quel est son chemin d'index. Controller doit contenir tout code manipulant des éléments d'interface utilisateur basés sur le modèle de données ou modifiant des données basées sur des interactions d'interface utilisateur. (Voir MVC .)
Essayez ceci avec votre UITableViewCell:
NSIndexPath *indexPath = [(UITableView *)self.superview indexPathForCell: self];
EDIT: Cela semble ne pas fonctionner avec iOS 8.1.2 et plus. Merci à Chris Prince pour l'avoir signalé.
Vous pouvez essayer cette astuce simple:
sur votre UITableViewCell
classe:
@property NSInteger myCellIndex; //or add directly your indexPath
et sur votre méthode cellForRowAtIndexPath
:
...
[cell setMyCellIndex : indexPath.row]
maintenant, vous pouvez récupérer votre index cellulaire n'importe où
Pour adresser ceux qui disent "c'est une mauvaise idée", dans mon cas, mon besoin est que j'ai un bouton sur ma UITableViewCell
qui, lorsqu'il est enfoncé, est une transition vers une autre vue. Comme il ne s’agit pas d’une sélection sur la cellule elle-même, [self.tableView indexPathForSelectedRow]
ne fonctionne pas.
Cela me laisse deux options:
NSFetchedResultsController
car je ne veux pas vouloir stocker tous les objets en mémoire, en particulier si la table est longue.NSIndexPath
par un hack, mais c'est finalement moins cher que de stocker des objets en mémoire.indexPathForCell:
est la méthode correcte à utiliser, mais voici comment je le ferais (ce code est supposé être implémenté dans une sous-classe de UITableViewCell
:
// 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. Mon vrai code accède à tout cela à partir de la vue tableau, mais je donne un exemple de la raison pour laquelle une personne pourrait vouloir faire quelque chose comme ceci directement dans la cellule du tableau.
Pour Swift
let indexPath :NSIndexPath = (self.superview.superview as! UITableView).indexPathForCell(self)!
La réponse à cette question m'a en fait beaucoup aidé.
J'ai utilisé NSIndexPath *indexPath = [self.tableView indexPathForCell:sender];
La sender
dans mon cas était une UITableViewCell
et provient de la méthode prepareForSegue
.
J'ai utilisé ceci parce que je n'avais pas un TableViewController
mais j'avais UITableView property outlet
Je devais trouver le titre de la variable Cell
et donc connaître son chemin indexPath.
J'espère que cela aide n'importe qui!
Sur iOS 11.0, vous pouvez utiliser UITableView.indexPathForRow(at point: CGPoint) -> IndexPath?
:
if let indexPath = tableView.indexPathForRow(at: cell.center) {
tableView.selectRow
(at: indexPath, animated: true, scrollPosition: .middle)
}
Il obtient le point central de la cellule, puis tableView renvoie le chemin indexPath correspondant à ce point.
essayez ceci (cela ne fonctionne que si la table a une seule section et que toutes les cellules ont des hauteurs égales):
//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
Pour donner accès à ma cellule, j'ai fait quelque chose comme ça:
J'ai une extension de l'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
}
}
Et puis .. dans ma cellule
class SomeCell: UITableViewCell {
func someMethod() {
if let myViewController = self.parentViewController as? CarteleraTableViewController {
let indexPath : IndexPath = (myViewController.tableView).indexPath(for: self)!
print(indexPath)
}
}
}
C'est tout moi.
Meilleures salutations.
Essayez ceci avec votre UITableViewCell:
NSIndexPath *indexPath = [(UITableView *)self.superview.superview indexPathForCell:self];