如何从 Cell 中获取 UITableViewCell indexPath?

Posted

技术标签:

【中文标题】如何从 Cell 中获取 UITableViewCell indexPath?【英文标题】:How to get UITableViewCell indexPath from the Cell? 【发布时间】:2013-03-20 15:57:22 【问题描述】:

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

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

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

【问题讨论】:

就像您的其他question 从单元格获取UITableView - 为什么?这似乎是一个糟糕的设计决策的代码味道 - 没有多少合法的用例让一个单元知道它是 indexPath 或者它是否在屏幕上。 我同意 Paul.s 的评论。你应该说明你为什么要这样做,因为你试图做的可能是个坏主意。 @Paul.s 我在问题中发布了我的程序设计。这可能是不好的编程习惯,在这种情况下,如果您可以提出替代方案,那将非常有帮助。我对可可很陌生,对一般编程也比较陌生。 值得注意的是 indexPathsForVisibleRows 存在 - 当您想知道滚动中的“您在哪里”时,这一点至关重要。 【参考方案1】:
NSIndexPath *indexPath = [self.tableView indexPathForCell:cell];

它有助于阅读UITableView documentation,即使这被一些人认为是有争议的(参见下面的 cmets)。

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

【讨论】:

如果您阅读该问题,它会有所帮助。这是来自一个 UITableViewCell,它没有 tableView 属性(并且从所有帐户来看,不应该)。 @voidref 这也有助于思考这个问题;-)。单元不知道它的索引路径是什么。所以这段代码应该在控制器中。有关 MVC 的背景信息,请参阅Cocoa Core Competencies。 从一开始就很明显的人需要正确的答案并不重要。 不回答原始问题。有时细胞需要知道它的路径。例如,如果您在子类单元格上实现了某种形式的滑动操作,您可能需要通知父视图当前正在滑动哪个单元格。一种方法是让 parentView 中的方法循环遍历 tableView 单元格并检查已在单元格中设置的 iVar。更好的方法是让单元格通过委托方法通知 parentView 它是 indexPath ...因此单元格需要知道它是 indexPath。所以 Mundi,最好先回答这个问题,然后提出你的观点。 索引路径是单元格和数据模型之间的“胶水”,属于控制器。上面的长评论实际上是错误的。 @wuf810 ...因为控制器知道单元格和索引路径之间的关系,所以单元格不知道(也不应该)。【参考方案2】:

在你的 UITableViewCell 中尝试这个:

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

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

【讨论】:

在 iOS 8.1.2 中,表格视图单元格的父视图是 UITableViewWrapperView 类型。它的超级视图是表视图类型。但我认为我们在这里踏上了危险的道路...... 这一切都回到了“单元格不知道它的索引路径是什么”。争论。访问 superview 几乎总是一种 hack,一段时间后它不起作用也就不足为奇了。 完全正确fatuhoku,知道索引路径不是cell的问题【参考方案3】:

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

    @property (weak,nonatomic)UITableView *tableView;

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

    cell.tableView = tableView;

    现在只要你需要 cell 的 indexPath:

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

【讨论】:

这是可行的,因为我们只存储了一个指向 tableView 本身的指针,但是 indexPathForCell 可靠吗?我认为这仅提供可见单元格的 indexPath 吗?【参考方案4】:

你可以试试这个简单的技巧:

在你的UITableViewCell 课堂上:

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

在你的 cellForRowAtIndexPath 方法上:

...
[cell setMyCellIndex : indexPath.row]

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

【讨论】:

您需要记住在重新排序或删除单元格后手动更新此信息。【参考方案5】:

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

这给我留下了两个选择:

    将我需要传递到视图中的对象存储在表格单元格本身中。虽然这可行,但它会破坏我拥有NSFetchedResultsController 的意义,因为我没有 em> 希望将所有对象存储在内存中,尤其是在表很长的情况下。 使用索引路径从 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;

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

【讨论】:

【参考方案6】:

快速

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

【讨论】:

【参考方案7】:

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

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

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

我使用它是因为我确实没有TableViewController但我有UITableView property outlet

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

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

【讨论】:

【参考方案8】:

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

【讨论】:

【参考方案9】:

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

【讨论】:

【参考方案10】:

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

最好的做法是找出失败的案例。

【讨论】:

【参考方案11】:

在你的 UITableViewCell 中尝试这个:

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

【讨论】:

【参考方案12】:

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

这就是我的全部。

最好的问候。

【讨论】:

以上是关于如何从 Cell 中获取 UITableViewCell indexPath?的主要内容,如果未能解决你的问题,请参考以下文章

如何从按钮单击中获取 UITableview cell.textlabel.text 值?

uitableview 单元格的背景

如何在 TableView Cell 中设置随机图像

如何获取tableview中当前选中的cell

从xlsx文件获取数据时无法从文本单元格获取数值

如何获取UIPickerView中选中的cell的值