使用Core Data在UITableView中显示“找不到行”消息

时间:2012-09-01 21:00:43

标签: iphone core-data uitableview nsfetchedresultscontroller

我已经实现了一个使用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开发的新手,我想学习最佳实践)。感谢。

4 个答案:

答案 0 :(得分:12)

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

答案 1 :(得分:7)

我在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必须是不透明的才能隐藏标签。或者需要根据行数切换标签的隐藏属性。

答案 2 :(得分:1)

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

UIViewControllerUITableView(控制器是数据源和您的表的委托)和UILabel(或包含UIView的{​​{1}}组成a UILabel)显示空行消息。

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

这种方法可能很费力,但我认为避免攻击NSFetchResultsController和数据源是件好事。此外,您可以完全控制安排空信息的位置。

正如@Rog建议你也可以使用表格视图标题来显示该消息。如你所愿。

希望它有所帮助。

答案 3 :(得分:1)

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

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

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