IndexPathForCell 和 IndexPathForRowAtPoint 崩溃
Posted
技术标签:
【中文标题】IndexPathForCell 和 IndexPathForRowAtPoint 崩溃【英文标题】:IndexPathForCell and IndexPathForRowAtPoint crash 【发布时间】:2013-04-22 22:27:03 【问题描述】:我有 UITableViewController
带有静态分组单元格。在特定视图中,我想删除一些单元格。如果我只是隐藏它们,它会留下一个空白空间,所以我想将单元格的 rowHeight
设置为 0
。我在执行此操作时遇到了麻烦,因为我似乎无法获得要隐藏的单元格的 indexPath。我通过 IB 连接引用了它。阅读后,似乎最好的方法是通过heightForRowAtIndexPath
方法。这是我的代码:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
NSIndexPath *myIndexPath = [self.tableView indexPathForRowAtPoint:self.billToPostalCell.center];
//crashes here
if ([indexPath isEqual:myIndexPath])
return 0;
return 44;
在此之前,我正在尝试IndexPathForCell
,但也会崩溃。根据我的阅读,heightForRowAtIndexPath
应该可以工作,即使单元格不可见。当它崩溃时,调试器中也没有任何显示。
【问题讨论】:
你试过注销myIndexPath
返回的行吗?
【参考方案1】:
你正在做的是导致无限递归导致......等待它......堆栈溢出!
在heightForRowAtIndexPath:
方法中,您不能向表格询问单元格或向索引路径询问行,因为这些方法需要知道单元格的高度。所以这些调用导致heightForRowAtIndexPath:
被调用。而且由于您随后再次调用了相同的违规方法,因此这种情况一直持续到事情进展顺利。
由于您的目标是隐藏单元格,因此您应该使用正确的 UITableView
方法 (deleteRowsAtIndexPaths:withRowAnimation:
) 从表格中删除单元格。当然,您需要先更新您的数据模型(以删除行)。
【讨论】:
谢谢,我具体如何先更新数据模型?这些是静态单元格,其中包含 IB 连接的 UITextField 和 UILabel,它们在viewWillAppear
方法中单独填充。仅调用 deleteRowsAtIndexPaths:withRowAnimation
方法就会引发此错误:'NSInternalInconsistencyException',原因:'无效更新:第 4 节中的行数无效。从谷歌搜索,我知道我需要按照你说的更新数据源模型。
您的“numberOfRowsForSection”方法应根据您拥有的某些数据模型返回一个数字(未硬编码为某个特定值)。这是您需要更新的数据模型。这通常是某种数组。先从数组中删除对象,然后告诉表删除行。
就是这样。在这种情况下,没有数组。 tableView 的 dataSource 委托未连接视图控制器。而且我没有实现任何 dataSource 委托的方法。在 IB 中绘制的每个单元格都有一个通过 IB 出口连接到代码的 textField。然后在代码中,我像这样填充文本字段:self.myTextField.text = self.customer.someString
。在删除行之前,我尝试将单元格设置为零,但没有骰子。
我找到了这个答案,它对我的后续问题有所帮助。 ***.com/a/9434849/1672161 感谢您回答我最初的问题。【参考方案2】:
您不应该更改单元格的可见性和高度。如果您想删除单元格并稍后添加它们,或者永远不要添加它们,您应该使用 UITableView 上的插入和删除方法。这是一个很好的起点documentation。
此外,您不应该在tableView:heightForRowAtIndexPath:
中使用tableView 上的方法,例如indexPathForRowAtPoint:
,因为tableView 必须先计算出自己的高度,然后才能计算出这样的东西。您可能会遇到错误,因为您处于无限循环中。
【讨论】:
【参考方案3】:使用-deleteRowsAtIndexPaths:withRowAnimation
删除行。切勿操纵单元格的可见性来代替删除它;这可能会导致严重的内存问题,并且只是一般的不良做法。只需传入一个 NSArray
填充您要删除的行的 NSIndexPath
。
您提到indexPathForRowAtPoint:
方法不起作用。这几乎肯定是您传递给它的点的问题。请务必注销 billToPostalCell.center
的值,以确保您传递的是合法值。但是,如果您正在处理静态单元格,则确实不需要这样做,因为您应该已经知道索引路径(至少对于初始单元格删除而言)。
正如其他人所提到的,关于删除单元格的documentation 提供了您应该需要的所有其他信息。
【讨论】:
这是一个我忘了提的好点,因为您使用的是静态单元格,只需与静态 indexPath.row 进行比较即可。以上是关于IndexPathForCell 和 IndexPathForRowAtPoint 崩溃的主要内容,如果未能解决你的问题,请参考以下文章
重新加载UITableView数据后,indexPathForCell返回null
self.tableView.indexPathForCell(cell) 返回错误的单元格?
在单元格中单击时,tableView:indexPathForCell 返回 nil
UITableViewCell indexPathForCell:iOS 7 上的应用程序崩溃