如何从Cell获取UITableViewCell indexPath?

时间:2013-03-29 21:44:24

标签: iphone ios objective-c xcode cocoa

如何从一个单元格中indexPath获取UITableView

我搜索了堆栈溢出和谷歌,但所有信息都是相反的。有没有办法访问superView / UITableView,然后搜索单元格?

有关上下文的更多信息:我有两个类,一个名为Cue,一个名为CueTableCellUITableViewCell的子类){{1} }是CueTableCell的可视化表示(两个类都有指向彼此的指针)。 Cue个对象位于链接列表中,当用户执行某个命令时,需要选择下一个Cue的可视化表示(CueTableCell)。因此,Cue类会在列表中的下一个Cue调用select方法,该方法会从Cue检索UITableView并调用其cell },它需要selectRowAtIndexPath:animated:scrollPosition:的{​​{1}}。

12 个答案:

答案 0 :(得分:129)

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

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

单元格无法知道其索引路径是什么。 控制器应包含基于数据模型操纵UI元素或基于UI交互修改数据的任何代码。 (见MVC。)

答案 1 :(得分:24)

尝试使用UITableViewCell:

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

编辑:似乎这不适用于iOS 8.1.2及更高版本。感谢Chris Prince的指点。

答案 2 :(得分:11)

您可以尝试这个简单的提示:

UITableViewCell班级上:

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

以及cellForRowAtIndexPath方法:

...
[cell setMyCellIndex : indexPath.row]

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

答案 3 :(得分:10)

  1. 将弱的tableView属性放在单元格的.h文件中,如:

    @property (weak,nonatomic)UITableView *tableView;

  2. 在cellForRowAtIndex方法中指定属性,如:

    cell.tableView = tableView;

  3. 现在,只要您需要cell的indexPath:

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

答案 4 :(得分:9)

为了解决那些说“这是一个坏主意”的人,在我的情况下,我需要的是我的UITableViewCell上有一个按钮,当按下时,是从另一个角度来看。由于这不是对单元格本身的选择,[self.tableView indexPathForSelectedRow]不起作用。

这给我留下了两个选择:

  1. 将我需要传递的对象存储到表格单元格本身的视图中。虽然这样可行,但它会让我失去NSFetchedResultsController因为我不要想要将所有对象存储在内存中,特别是如果表很长。
  2. 使用索引路径从获取控制器中检索项目。是的,看起来很难看,我必须通过黑客找出NSIndexPath,但它最终比将对象存储在内存中。
  3. 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;
    }
    

    P.S。我的真实代码确实从表视图中访问了所有这些,但我给出了一个例子,说明为什么有人可能想直接在表格单元格中执行此类操作。

答案 5 :(得分:6)

快速

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

答案 6 :(得分:4)

这个问题的答案实际上帮助了我很多。

我使用了NSIndexPath *indexPath = [self.tableView indexPathForCell:sender];

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

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

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

希望这对任何人都有帮助!

答案 7 :(得分:2)

在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。

答案 8 :(得分:1)

试试这个(只有当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;

答案 9 :(得分:1)

Swift 3.0 及以上-

如果需要从自定义单元格中获取索引路径-

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")
}

寻找失败案例是一种很好的做法。

答案 10 :(得分:0)

尝试使用UITableViewCell:

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

答案 11 :(得分:0)

  

Swift 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)
        }
    }
}

就这样形成了我。

最诚挚的问候。