2013-03-29 65 views
57

我如何从单元格获得indexPathUITableView如何从单元格获取UITableViewCell indexPath?

我已经搜索了周围的堆栈溢出和谷歌,但所有的信息是相反的。有没有办法访问superView/UITableView然后搜索单元?有关上下文

的更多信息:有两类,我有,一个被称为Cue和一个被称为CueTableCell(这是UITableViewCell的子类)CueTableCellCue视觉表示(这两个类具有指向彼此)。 Cue对象位于链接列表中,并且当用户执行某个命令时,需要选择下一个Cue的可视表示(CueTableCell)。因此,Cue类在列表中的下一个Cue上调用select方法,该方法从cell中检索UITableView并调用其selectRowAtIndexPath:animated:scrollPosition:,为此需要UITableViewCellindexPath

+2

就像从你的其他[问题](http://stackoverflow.com/questions/15711645/how-to-get-uitableview-from-uitableviewcell)获取单元格中的“UITableView” - 为什么?这看起来像是一个糟糕的设计决定的代码味道 - 对于一个单元来说,它没有太多合法的用例来知道它是否是indexPath,或者它是否在屏幕上。 –

+0

我同意Paul.s的评论。你应该说明你为什么要这样做,因为你想要做的事可能是一个坏主意。 – rdelmar

+0

@ Paul.s我在问题中发布了我的程序设计。这可能是不好的编程实践,在这种情况下,如果你可以提出一个替代方案,那将是非常有用的。一般来说,我对可可非常陌生,对编程也比较陌生。 –

回答

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

它可以帮助阅读documentation,即使这是被一些认为是有争议的(见下面的评论)。

小区没有业务知道它的索引路径是什么。 控制器应包含任何基于数据模型操纵UI元素或基于UI交互修改数据的代码。 (见MVC。)

+30

如果你阅读这个问题,它会有所帮助。这是来自UITableViewCell,它没有tableView属性(并且不是所有帐户都不应该)。 – voidref

+10

@voidref它也有助于思考这个问题;-)。小区没有业务知道它的索引路径是什么。所以这段代码应该在控制器中。有关MVC的背景信息,请参阅[Cocoa Core能力](https://developer.apple.com/library/ios/#documentation/General/Conceptual/DevPedia-CocoaCore/MVC.html)。 – Mundi

+0

不够公平,但你的原始回答应该已经解释了。 – shim

23

这个从你的UITableViewCell尝试:

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

编辑:看来,这并不在iOS 8.1.2和进一步的工作。感谢Chris Prince指出它。

+7

在iOS 8.1.2中,表格视图单元格的超视图属于UITableViewWrapperView类型。该超级视图是类型表视图。但我认为我们正在踩着危险地带...... –

+1

这一切都可以追溯到“细胞没有知道它的索引路径是什么。”论据。访问超级视图几乎总是一种黑客攻击,一段时间后它不起作用也就不足为奇了。 – fatuhoku

+0

完全正确的fatuhoku,它不是知道索引路径的单元格的事 –

3

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

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

sender在我的情况是UITableViewCell和来自prepareForSegue方法。

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

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

希望这有助于任何人!

7

为了解决这些谁说“这是一个坏主意”,在我的情况,我需要这是我对我的UITableViewCell一个按钮,按下时,是SEGUE另一种观点。由于这不是电池本身的选择,所以[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; 
} 

PS我真正的代码做这个访问的所有从表中的观点,但我给的,为什么有人会想直接做这样的事情在表格单元格为例

10
  1. 把弱的tableView财产细胞的.h文件中,如:。

    @property (weak,nonatomic)UITableView *tableView;

  2. 指定在cellForRowAtIndex方法类似物业:

    cell.tableView = tableView;

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

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

+0

这是有效的,因为我们只存储一个指向tableView本身的指针,但是,indexPathForCell是可靠的吗?我认为这只提供可见单元格的indexPath否? – jcpennypincher

0

这种尝试从您的UITableViewCell:

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

自ios 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; 
10

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

UITableViewCell类:

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

并在您cellForRowAtIndexPath方法:

... 
[cell setMyCellIndex : indexPath.row] 
现在

,您可以检索任何地方

+2

您需要记住在重新排序或删除单元格后手动更新此信息。 – konrad

5

你的指数为SWIFT

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

在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对应直到那一刻。

相关问题