没有重复使用表格单元格的索引路径

Posted

技术标签:

【中文标题】没有重复使用表格单元格的索引路径【英文标题】:No index path for table cell being reused 【发布时间】:2013-08-31 16:29:35 【问题描述】:

这开始突然发生。任何想法:代码:

CUSTOMCLASSNAME(我已经替换了实际的类名,因为它包含客户端的名称。)

初始化我的 tableView:

[self.tableView registerClass:[CUSTOMCLASSNAME class] forCellReuseIdentifier:[self reuseIdentifier]];

在行的单元格中:

您好,标题正在控制台中打印。这是我的 cellForRow:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 

    AVTCheckListTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:[self reuseIdentifier] forIndexPath:indexPath];

    [self configureCell:cell atIndexPath:indexPath];

    return cell;


- (void)configureCell:(AVTCheckListTableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath 
    ChecklistGroup *group = [self.checklistFetchedResultsController.fetchedObjects objectAtIndex:indexPath.section];

    ChecklistItem *item = [self getChecklistItemForIndexPath:indexPath];

    [cell setSelectionStyle:UITableViewCellSelectionStyleNone];
    [[cell cellTextView] setAttributedText:[[item checked] boolValue] ? [[NSAttributedString alloc] initWithString:[item name] attributes:@ NSStrikethroughStyleAttributeName : @(NSUnderlineStyleSingle)  ] : [[NSAttributedString alloc] initWithString:[item name]]];
    [[cell cellTextView] setUserInteractionEnabled:[[group isUserDefined] boolValue]];
    [[cell cellTextView] setTag:indexPath.row];
    [[cell cellTextView] setDelegate:self];
    [[cell tickImage] setHidden:![[item checked] boolValue]];


//Method that returns re-use:

- (NSString *) reuseIdentifier 
    return @"CheckListTableView";

【问题讨论】:

突然发生了什么? 您好,错误是标题。。然后,表格视图在滚动时会出现不稳定的行为。直到所有单元格都已加载,但由于它们没有被重复使用,这是一个问题。 完全不清楚您遇到了什么问题。请在您的帖子中添加更多信息来解释您的问题。如果您的应用抛出异常,也包括在内。 您应该发布整个 cellForRowAtIndexPath 方法。你怎么知道 indexPath 没有被重用? 您好,标题正在控制台中打印。这是我的 cellForRow: 【参考方案1】:

您可以尝试以下方法吗(前提是您对该索引路径中的单元格没有任何特定配置):-

CustomClassName *cell=[tableView dequeueReusableCellWithIdentifier:[self reuseIdentifier]];
if(cell==nil)

cell=[[CustomClassName alloc] initWithStyle:whatever_style reuseIdentifer:[self reuseIdentifier]];

如果上述方法不起作用,请同时发布您遇到的错误。

还可以查看以下链接:-

What is the meaning of the "no index path for table cell being reused" message in ios 6/7?

【讨论】:

INternal bug 似乎不是一个好的答案... 其他 tableviews 不这样做。【参考方案2】:

几天后我解决了这个问题。在我的自定义单元格中,我有一个 textView,当我将它添加到 contentView 时,我正在这样做:

[self.cellTextView setClearsOnInsertion:YES];

这是问题的原因;以防其他人有类似的问题。

编码愉快:-)

【讨论】:

谁能解释为什么会导致这个问题? 我怀疑这与表格视图单元格的出列有关。不过我不能确定。【参考方案3】:

我刚刚找到了导致此错误消息的原因。

UITableViewCell 被用作普通视图。因此它的'indexPath 没有设置。在我们的例子中,viewForHeaderInSection 返回了一个:

希望这会有所帮助。

克里斯

【讨论】:

那么你做了什么来修复它? 我停止使用 UITableViewCell 作为普通视图 - 即在我需要创建普通视图的地方我使用 UIView 而不是 UITableViewCell。【参考方案4】:

tableView:viewForHeaderInSection:返回[cell contentView]而不是cell

编辑:这不知何故导致 UI 按钮上的长按手势崩溃。为了解决这个问题,我放弃并使用了另一个带有单个项目的部分作为假的部分标题。

【讨论】:

这为我解决了。就我而言,它是 viewForFooterInSection 方法。谢谢! 我可以确认,长按此部分会导致应用崩溃 但是我最终要做的是向内容视图添加一个 LongPressGesture,这会阻止将 LongPress 事件传递给在我们返回内容视图时已经释放的单元格,这就是导致崩溃的原因并解决问题。 代码:UILongPressGestureRecognizer *touchDown = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(didTouchDownPress:)]; touchDown.minimumPressDuration = .001; [headerView.contentView addGestureRecognizer:touchDown]; 这让我可以突出显示 Begin 状态的所有内容并处理状态结束的操作【参考方案5】:

好吧,我只是用了一天的大部分时间试图弄清楚这一点,所以希望这种替代解释可以节省其他人一些时间。

我有一个表格视图,有时在加载时会发出此消息。事实证明,这是由在加载视图时触发 Core Data 对象的 KVO 通知引起的。 (在观察到变化时,我的控制器尝试在有问题的 tableview 上调用 reloadData。通过在视图完成加载之前不观察对象来修复(以前,一旦通过访问器分配对象,我就开始观察对象)

TLDR:检查您是否尝试从主线程以外的其他地方重新加载数据。

甚至更好:

如果您(我发现您确实应该)使用子托管对象上下文并且仅在合理的时间将更改合并回主线程上的主 MOC,那么您就不会遇到这个问题。

【讨论】:

【参考方案6】:

就我而言,此错误仅出现在 iPhone(而不是 iPad)上,因为我已将 [self.tableView beginUpdates]; 和后来的 [self.tableView endUpdates]; 放在 [UIView transitionWithView:duration:options:animations:compeletion]; 中。为了解决这个问题,我刚刚删除了开始/结束更新,因为我更喜欢渐变动画而不是渐变加上动画单元格高度变化。

【讨论】:

【参考方案7】:

我在tableView:viewForHeaderInSection 中返回UITableViewCell 时遇到问题,但返回[cell contentView] 会导致单元格内的任何按钮崩溃,并且在单元格周围设置视图包装器似乎很浪费。相反,我将我的 UITableViewCell 类更改为 UITableViewHeaderFooterView,它就像一个魅力!

如果您遇到此问题:

在 UITableViewHeaderFooterView 上设置背景颜色已被弃用。请改用 contentView.backgroundColor。

请记住将笔尖的背景颜色更改为默认值。

【讨论】:

【参考方案8】:

如果您使用单元格作为标题视图部分标题,则必须将其放入容器中,然后返回容器视图以防止“表格单元格没有索引路径被重用”。示例代码如下。

-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section 
    CustomerCellHeader *headerViewCell = [tableView dequeueReusableCellWithIdentifier:kCustomerCellHeaderIdentifier];
    headerView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
    [headerView addSubview:headerViewCell];
    return headerView;

【讨论】:

【参考方案9】:

我遇到了同样的问题。当我滚动并重复使用单元格时会出现此消息。

很多答案都谈到了 viewForHeaderInSection,但我没有使用它们。如果有人有类似的问题,我特此展示我的解决方案。

我在每个单元格内的文本字段中添加了观察者。我想知道这是否是导致此问题的观察者,因为在回收单元时我没有删除观察者。

所以当一个单元格被定义时,我移除了观察者。

看来问题解决了。我不能保证。

【讨论】:

【参考方案10】:

我在viewForHeaderInSection 实施过程中发现了这个警告。

这是我在 Swift 2.x 中的解决方案:

let headerView = self.tableView.dequeueReusableCellWithIdentifier("MyCell") as! MyCell
let containerView = UIView(frame:headerView.frame)
headerView.autoresizingMask = [.FlexibleWidth, .FlexibleHeight]
headerView.myLabel.text = "section title 1"
containerView.addSubview(headerView)
return containerView

这是 Swift 3 版本:

let headerView = self.tableView.dequeueReusableCell(withIdentifier: "MyCell") as! MyCell
let containerView = UIView(frame:headerView.frame)
headerView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
headerView.myLabel.text = "section title 1"
containerView.addSubview(headerView)
return containerView

【讨论】:

这个解决方案在 Objective C 中对我有用,谢谢 :-) 想补充一点,我确实必须在我的标题单元格上将 TranslatesAutoresizingMaskIntoContraints 设置为 NO 并将其约束到我的 containerView。对于在我的 viewWillTransitionToSize:withSizeCoordinator: 中的旋转,我必须添加一个调用来让我的表格视图重新加载它的数据,然后我在我的视图上设置需要布局。希望此信息也对其他人有所帮助。【参考方案11】:

它在 swift 2.1 中帮助了我

  func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView 
            let headerCell:SBCollapsableTableViewHeader = self.friendsInfoTableView.dequeueReusableCellWithIdentifier("HeaderCell") as! SBCollapsableTableViewHeader
            let containerView = UIView(frame:headerCell.frame)
            headerCell.delegate = self
            headerCell.titleLabel.font = UIFont.boldSystemFontOfSize(15)
            headerCell.titleLabel.text = "\(self.ObjectArray[section].sectioName)"
            headerCell.collapsedIndicatorLabel.text = collapsed ? "+" : "-"
            headerCell.tag = section
            headerCell.backgroundColor =  UIColor(red:72/255,green:141/255,blue:200/255,alpha:0.9)
            containerView.addSubview(headerCell)
            return containerView
    

【讨论】:

【参考方案12】:

我收到了同样的错误,但原因不同。

我有一个自定义 UITableViewCell,它将 UITextField 之一设置为成为FirstResponder。返回此自定义单元格的多个实例时发生错误。

我只是将自定义单元格的第一个实例设置为 becomeFirstResponder 并解决了问题。

【讨论】:

【参考方案13】:

就我而言(相当愚蠢的一个),我在cellForRowAt 中使用了if let 语法,如下所示:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 
    if let cell = tableView.dequeueReusableCell(withIdentifier: "carCell", for:
    indexPath) as? carTableViewCell 
        // Did some stuff here
        return CarTableViewCell()
    else 
        return CarTableViewCell()    
    

如你所见,我返回了一个通用的 carTableViewCell(),这就是给我这个卑鄙错误的原因...... 我希望它会帮助某人哈哈(:

编码愉快!

【讨论】:

以上是关于没有重复使用表格单元格的索引路径的主要内容,如果未能解决你的问题,请参考以下文章

自定义单元格的“没有重复使用表格单元格的索引路径”问题

没有重复使用表格单元格的索引路径

如何在基于部分的表格视图中获取开关更改事件中单元格的索引路径

分组表视图中单元格的索引路径

使用VAB控制单元格的跳转路径

如何查找选定集合视图单元格的索引路径?