【问题标题】:Displaying a "No rows found" message in UITableView with Core Data使用 Core Data 在 UITableView 中显示“未找到行”消息
【发布时间】:2012-08-27 05:13:30
【问题描述】:

我已经实现了一个使用 UITableViewController/UITableView 和 Core Data 的 iPhone 应用程序。此外,我使用 NSFetchedResultsController 来管理表数据。这一切都非常简单,而且效果很好。然后我决定当没有找到/检索到行时,我应该在 UITableView 中显示一条消息。在对此进行研究之后,似乎最好的方法(也许是唯一的方法)是返回一个包含消息的“虚拟”单元格。但是,当我这样做时,我从运行时系统中得到一个讨厌的图,它抱怨(并且理所当然地)数据不一致:“无效更新:无效的节数。表视图中包含的节数......”。以下是相关代码:

- (NSInteger) numberOfSectionsInTableView: (UITableView *)tableView
{
    if ([[self.fetchedResultsController fetchedObjects] count] == 0) return 1;
    return [[self.fetchedResultsController sections] count];
}

- (NSInteger) tableView: (UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    if ([[self.fetchedResultsController fetchedObjects] count] == 0) return 1;
    id <NSFetchedResultsSectionInfo> sectionInfo = [[self.fetchedResultsController sections] objectAtIndex: section];
    return [sectionInfo numberOfObjects];
}

- (UITableViewCell *) tableView: (UITableView *)tableView cellForRowAtIndexPath: (NSIndexPath *)indexPath
{
    if ([[self.fetchedResultsController fetchedObjects] count] == 0) {
        UITableViewCell *cell = [[UITableViewCell alloc] init];
        cell.textLabel.text = @"No widgets found.";
        return cell;
    }

    STCellView *cell = (STCellView *)[tableView dequeueReusableCellWithIdentifier: @"ShieldCell"];
    [self configureCell: cell atIndexPath: indexPath];
    return cell;
}

我已阅读类似问题的回复,看来我应该使用

insertRowsAtIndexPaths: withRowAnimation:

将“虚拟”消息行插入我的表中。但是,这也意味着在插入真实行时删除“虚拟”行。我可以做到这一点,但似乎应该有一种更简单的方法来实现这一点。我要做的就是显示一条消息,指示表中没有行(够简单吗?)。所以,我的问题是:有没有办法在 UITableView 中显示一条消息而不使用“虚拟”单元格方法,或者有没有办法让 UITableViewController/NSFetchResulsController 相信这只是一个“虚拟”行,他们不应该得到因为它不是表格中的真实行(从我的角度来看),所以对此感到不安?

您能提供的任何帮助都将不胜感激(我是 iPhone 开发的一个苦苦挣扎的新手,我想学习最佳实践)。谢谢。

【问题讨论】:

  • 与其破解 tableview 数据源以获得预期的 UI,为什么不将“No rows found”消息添加到 tableview 标头?
  • 如果您的表格视图中只有一个部分,这是最好的方法。请参阅下面的多个部分的方法
  • @Rog 这是完美的答案。在 viewWillAppear 中,如果行数为 0,我会加载一个表格视图标题。不幸的是,因为您没有输入这个作为答案,我无法选择它,但它(在我看来)是最干净和最好的答案。非常感谢。
  • 谢谢,很高兴它对你有用。我已将其添加为答案,以便其他人将来可以轻松找到它,因此下次您在附近时随时将其标记为正确。

标签: iphone core-data uitableview nsfetchedresultscontroller


【解决方案1】:

您应该将“未找到行”消息添加到 tableview 标题中,而不是使用 tableview 数据源来获取预期的 UI。

【讨论】:

  • 这是最干净和最好的答案。非常感谢!!
  • 我喜欢这个声音。你是说你观察可用的行数,然后有条件地显示/隐藏 tableview 标题?还是总是显示标题并将其文本更改为“未找到行”?
  • Andy - 你也可以使用页脚。
  • 如果我想显示一个代表“未找到数据”的全屏图像,我们该怎么做?
  • @Satyam 你的工作是什么?我相信我也有类似的问题。
【解决方案2】:

我在 viewDidLoad 中做了如下操作。

UILabel *label = [[UILabel alloc] init];
[label setTextColor:[UIColor lightGrayColor]];
[label setText:@"No widgets found."];
[label sizeToFit];
label.frame = CGRectMake((self.tableView.bounds.size.width - label.bounds.size.width) / 2.0f,
                         (self.tableView.rowHeight - label.bounds.size.height) / 2.0f,
                         label.bounds.size.width,
                         label.bounds.size.height);
[self.tableView insertSubview:label atIndex:0];

在这种情况下,每个 TableViewCells 必须是不透明的才能隐藏标签。或者需要根据行数来切换标签的隐藏属性。

【讨论】:

    【解决方案3】:

    我之前使用过的另一种方法是使用 Core Data 为您管理更新,方法是在模型类中未检测到行的部分插入“无行”实体,该部分处理数据更新.

    有很多方法可以实现这一点,例如将名称/标题字段设置为已知状态消息或实体内的标志。插入后,您可以在 cellForRowAtIndexPath 委托方法中检测到“无行”实体,并插入替代表格单元格以显示消息。

    在刷新该部分的数据之前删除“无行”实体。

    【讨论】:

    • 为什么投反对票?我只是提供了一个可行的解决方案来处理多个部分!
    【解决方案4】:

    显示空消息的简单建议是将控制器重新排列为简单的UIViewController(而不是UITableViewController)。

    这个UIViewControllerUITableView(控制器是数据源和表的委托)和UILabel(或包含UILabelUIView)组成,显示空行消息。

    通过这种方式,您可以根据检索到的行来控制表格和标签的可见性。

    这种方法可能很费力,但我认为最好避免入侵 NSFetchResultsController 和数据源。此外,您可以完全控制空消息的位置。

    正如@Rog 所建议的,您还可以使用表格视图标题来显示该消息。随你喜欢。

    希望对你有帮助。

    【讨论】:

    • 这不是一个好的解决方案,因为您不能正确使用 UITableViewController' 内置 UIRefreshControl 子类化 UIViewController。最好使用视图控制器包含来嵌入表格视图控制器子类,并在容器视图控制器中处理空视图。
    • @amb 这是一个可能的解决方案......操作人员没有请求使用下拉刷新功能......在我看来,这里的遏制太多了。感谢您的评论。
    • 嗯,你说得对,但是当你必须显示一个空的表格视图消息时,同时使用UITableViewControllerUIRefreshControl 是很常见的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-12-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-24
    相关资源
    最近更新 更多