【问题标题】:cellForRowAtIndexPath isn't called after reloadRowsAtIndexPaths在 reloadRowsAtIndexPaths 之后不调用 cellForRowAtIndexPath
【发布时间】:2013-06-30 15:14:21
【问题描述】:

正如Apple Doc所说,

重新加载行会导致表视图向其数据源请求新的 该行的单元格。

我将 UITableView 与 NSFetchedResultsController 结合起来:

- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller
{
    if (self.tableView.isEditing) 
    {
        [self.tableView setEditing:NO animated:YES];
    }
    [self.tableView beginUpdates];
}

- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller
{
    [self.tableView endUpdates];

    [self updateTabItemBadge];
    [self.noDataView setHidden:![self isNoData]];

    WXINFO(@"controllerDidChangeContent");
}

在上述两个函数之间,我重新加载了目标单元格:

    case NSFetchedResultsChangeUpdate: {
        if (indexPath) {
            [tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone];
        }

我在 Line1563 处设置了一个断点,以检查 reloadRowsAtIndexPaths 是否已被调用,但之后,- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 没有被调用。

所以,我的单元格无法更新。

谁能告诉我为什么?谢谢。

【问题讨论】:

  • 重新加载目标单元格?那是我从未听说过的事情。甚至在 Visual Basic 中也没有...
  • 你调用reloadRowsAtIndexPaths:withRowAnimation:的方法是controller:didChangeObject:atIndexPath:forChangeType:newIndexPath:?
  • @leoformaggio 是的,当然。
  • @TBlue 目标单元格是 indexPath 处的单元格。
  • 可能有点傻,但是tableView其实指向的是目标tableView?将NSAssert(tableView, @"No Tableview!"); 放入NSFetchedResultsChangeUpdate: 外壳内以确保。

标签: iphone ios objective-c uitableview core-data


【解决方案1】:

这是我所做的一项工作,但它确实完成了工作。

 func tableView(_ tableView: UITableView, commit editingStyle:
    UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
        if editingStyle == UITableViewCellEditingStyle.delete {
            if itemDetailDict.count - 1 <= 0 {
                self.mainTable.beginUpdates()
                let cellOne = self.mainTable.cellForRow(at: indexPath)
                cellOne?.textLabel?.text = "There are no items."
                self.mainTable.reloadRows(at: [indexPath], with: .automatic)
                self.mainTable.endUpdates()
            } else {
                self.mainTable.beginUpdates()
                let removeKey = Array(itemDetailDict.keys)[indexPath.row]
                itemDetailDict.removeValue(forKey: removeKey)
                mainTable.deleteRows(at: [indexPath], with: .automatic)
                self.mainTable.endUpdates()
            }
        }
    }

基本上在删除行功能上,我希望用户能够删除该行,但是当只剩下一行时,我想在表格视图的单元格中显示一条默认消息。

为此,我更新了数据源,当字典中没有更多数据时,我更新单元格以显示文本,重新加载单元格,然后在我的 tableview 上调用 endUpdating。

我希望这会有所帮助。

【讨论】:

    【解决方案2】:

    我发现唯一可靠的方法是使用非动画动画。如果指定了任何其他动画,则重新加载正确发生。

    【讨论】:

      【解决方案3】:

      把它包起来:

      [tableView beginUpdates];
      [tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone];
      [tableView endUpdates];
      

      【讨论】:

      • 在controllerWillChangeContent & controllerDidChangeContent之间,有beginUpdates & endUpdates
      【解决方案4】:

      能否请您通过使用 [tableView reloadData] 重新加载 tableview 来检查?

      如果您只想更新一行而不重新加载表格,请检查“indexPath”类型。它应该是 NSIndexPath。

      【讨论】:

      • lldb 打印显示indexPathNSIndexPath
      • 这个 API 适合我。我观察到的一个可能原因是,当 indexPath 为 nil 时,不会调用 cellForRowAtIndexPath。
      • 或者,在你的代码中有self.tableView和tableView。您能否在重新加载行时尝试使用 self.tableView 。有可能tableView没有映射到控制器的tableView。
      • @Anand 请看控制台输出。
      猜你喜欢
      • 2013-12-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多