7

我已经实现了一个使用 UITableViewController/UITableView 和核心数据的 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

4 回答 4

13

与其使用 tableview 数据源来获取预期的 UI,不如将“No rows found”消息添加到 tableview 标题中。

于 2012-09-03T22:46:20.060 回答
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 必须是不透明的才能隐藏标签。或者需要根据行数来切换标签的隐藏属性。

于 2014-04-10T07:24:50.127 回答
2

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

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

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

于 2012-09-02T10:28:56.030 回答
1

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

UIViewController由 a UITableView(控制器是数据源和表的委托)和显示空行消息的 a UILabel(或UIView包含 a 的 a )组成。UILabel

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

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

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

希望能帮助到你。

于 2012-09-02T10:10:05.410 回答