繁体   English   中英

如何从 Cell 中获取 UITableViewCell indexPath?

[英]How to get UITableViewCell indexPath from the Cell?

我如何从单元格中获取UITableView indexPath

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

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

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

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

单元不知道它的索引路径是什么。 控制器应包含任何基于数据模型操作 UI 元素或基于 UI 交互修改数据的代码。 (请参阅MVC 。)

从你的 UITableViewCell 试试这个:

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

编辑:似乎这不适用于 iOS 8.1.2 及更高版本。 感谢克里斯普林斯指出它。

你可以试试这个简单的提示:

在您的UITableViewCell类上:

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

并在您的cellForRowAtIndexPath方法上:

...
[cell setMyCellIndex : indexPath.row]

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

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

这给我留下了两个选择:

  1. 将我需要传递到表格单元格本身中的视图的对象存储起来。 虽然这工作,它会破坏我的点有一个NSFetchedResultsController ,因为我希望所有的对象存储在内存中特别是如果该表是长。
  2. 使用索引路径从 fetch 控制器中检索项目。 是的,我必须通过 hack 找出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;
}

PS 我的真实代码确实从表格视图访问了所有这些,但我举了一个例子,说明为什么有人可能想直接在表格单元格中做这样的事情。

  1. 在单元格的 .h 文件中放置一个弱 tableView 属性,例如:

    @property (weak,nonatomic)UITableView *tableView;

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

    cell.tableView = tableView;

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

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

为迅捷

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

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

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

在我的例子中, sender是一个UITableViewCell并且来自prepareForSegue方法。

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

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

希望这可以帮助任何人!

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

试试这个(它只适用于 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;

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

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

从你的 UITableViewCell 试试这个:

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

斯威夫特 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)
        }
    }
}

这就是我的全部。

最好的祝福。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM