如何从单元格获取 UITableViewCell indexPath?

我如何,从一个细胞,得到它的 indexPath在一个 UITableView

我已经搜索了堆栈溢出和谷歌,但所有的信息是反过来的。是否有办法进入 superView/UITableView然后搜索细胞?

关于上下文的更多信息: 我有两个类,一个叫做 Cue,一个叫做 CueTableCell(它是 UITableViewCell的一个子类) CueTableCellCue的可视化表示(两个类都有指向对方的指针)。Cue对象在一个链表中,当用户执行某个命令时,需要选择下一个 Cue的可视化表示(CueTableCell)。因此,Cue类调用列表中下一个 Cue上的 select方法,它从 CueTableCell2中检索 CueTableCell1并调用它的 CueTableCell3,为此它需要 UITableViewCellCueTableCell4。

97977 次浏览
NSIndexPath *indexPath = [self.tableView indexPathForCell:cell];

它有助于阅读 UITableView 文档,即使这被一些人认为是有争议的(见下面的评论)。

单元格不需要知道它的索引路径是什么。控制器应该包含任何基于数据模型操作 UI 元素或基于 UI 交互修改数据的代码。(见 车祸)

在 UITableViewCell 中尝试这样做:

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

编辑: 看起来这个在 iOS8.1.2或者更高版本上无法工作。感谢 Chris Prince 指出这一点。

这个问题的答案实际上对我帮助很大。

我用的是 NSIndexPath *indexPath = [self.tableView indexPathForCell:sender];

我的案例中的 senderUITableViewCell,来自 prepareForSegue方法。

我用这个是因为我有 没有TableViewController但是我有 UITableView property outlet

我需要找出 Cell的标题,因此需要知道它的 indexPath。

希望这对大家有帮助!

为了解决那些说 “这是个坏主意”的人,在我的情况下,我需要的是在我的 UITableViewCell上有一个按钮,当按下按钮时,它是一个转向另一个视图的按钮。因为这不是细胞本身的选择,所以 [self.tableView indexPathForSelectedRow]不起作用。

这让我有两个选择:

  1. 将需要传递到视图中的对象存储在表单元格本身中。 虽然这个方法可行,但是它会破坏我使用 NSFetchedResultsController的要点,因为我 不要想要在内存中存储所有对象,特别是当表很长的时候。
  2. 使用索引路径从提取控制器检索项。是的,我不得不通过黑客技术来破解 NSIndexPath,这看起来很丑陋,但是它最终比在内存中存储对象要便宜。

indexPathForCell:是使用的正确方法,但是下面是我将如何做到这一点(假设这段代码是在 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;
}

附注: 我的真实代码确实从表格视图访问了所有这些,但是我给出了一个例子,说明为什么有人可能希望直接在表格单元格中执行类似的操作。

  1. 将弱 tableView 属性放在 cell 的. h 文件中,如下所示:

    @property (weak,nonatomic)UITableView *tableView;

  2. 在 cellForRowAtIndex 方法中分配属性,如下所示:

    cell.tableView = tableView;

  3. 现在,无论您在哪里需要单元格的 indexPath:

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

在 UITableViewCell 中尝试这样做:

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

尝试下面的方法(只有当 tableView 只有一个部分并且所有单元格具有相同的高度时,它才能工作) :

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

你可以试试这个简单的方法:

关于你的 UITableViewCell课程:

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

以及你的 cellForRowAtIndexPath方法:

...
[cell setMyCellIndex : indexPath.row]

现在,您可以在任何地方检索您的单元格索引

为了斯威夫特

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

在 iOS 11.0中,你可以使用 UITableView.indexPathForRow(at point: CGPoint) -> IndexPath?:

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

它获取单元格的中心点,然后 tableView 返回与该点对应的 indexPath。

斯威夫特4. x

为了进入我的手机,我做了这样的事:

我有一个 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
}
}

然后. . 在我的牢房类:

class SomeCell: UITableViewCell {


func someMethod() {
if let myViewController = self.parentViewController as? CarteleraTableViewController {
let indexPath : IndexPath = (myViewController.tableView).indexPath(for: self)!
print(indexPath)
}
}
}

这就是我的全部。

最好的问候。

Swift 3.0及以上版本 -

如果需要从自定义单元格中获取 indexpath-

if let tableView = self.superview as? UITableView{
if let indexPath = tableView.indexPath(for: self){
print("Indexpath acquired.")
}else{
print("Indexpath could not be acquired from tableview.")
}
}else{
print("Superview couldn't be cast as tableview")
}

最好的做法是留意失败的案例。