Iphone 显示一个";找不到行“;UITableView中包含核心数据的消息
我已经实现了一个iPhone应用程序,它使用UITableViewController/UITableView和核心数据。此外,我使用NSFetchedResultsController来管理表数据。这一切都很直截了当,效果很好。然后,我决定在找不到/检索到行时,应在UITableView中显示一条消息。在对此进行研究之后,似乎最好的方法(也许是唯一的方法)是返回一个包含消息的“虚拟”单元格。然而,当我这样做时,我从运行时系统中得到一个nastygram,它抱怨(并且理所当然地抱怨)数据不一致:“无效更新:无效的节数。表视图中包含的节数…”。以下是相关代码:Iphone 显示一个";找不到行“;UITableView中包含核心数据的消息,iphone,core-data,uitableview,nsfetchedresultscontroller,Iphone,Core Data,Uitableview,Nsfetchedresultscontroller,我已经实现了一个iPhone应用程序,它使用UITableViewController/UITableView和核心数据。此外,我使用NSFetchedResultsController来管理表数据。这一切都很直截了当,效果很好。然后,我决定在找不到/检索到行时,应在UITableView中显示一条消息。在对此进行研究之后,似乎最好的方法(也许是唯一的方法)是返回一个包含消息的“虚拟”单元格。然而,当我这样做时,我从运行时系统中得到一个nastygram,它抱怨(并且理所当然地抱怨)数据不一致:
- (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;
}
将“虚拟”消息行插入我的表。但是,这也意味着在插入实际行时删除“虚拟”行。我可以做到这一点,但似乎应该有一个更简单的方法来实现这一点。我只想显示一条消息,指示表中没有行(足够简单吗?)。所以,我的问题是:有没有办法在UITableView中显示消息而不使用“虚拟”单元格方法,或者有没有办法说服UITableViewController/NSFetchResultsController这只是一个“虚拟”行,他们不应该因为它不是表中的真实行(在我看来)而对此感到不安
如果您能提供任何帮助,我将不胜感激(我是一个在iPhone开发中苦苦挣扎的新手,我想学习最佳实践)。谢谢。我对显示空消息的简单建议是将控制器重新排列为简单的
UIViewController
(而不是UITableViewController
)
此UIViewController
由UITableView
(控制器是数据源和表的代理)和显示空行消息的UILabel
(或包含UILabel
的UIView
组成
通过这种方式,您可以基于检索到的行控制表和标签的可见性
这种方法可能很费劲,但我认为最好避免黑客攻击NSFetchResultsController
和数据源。此外,你还可以完全控制为你的空邮件安排位置
正如@Rog所建议的,您也可以使用表视图标题来显示该消息。随你的便
希望有帮助。我以前使用过的另一种方法是使用核心数据为您管理更新,方法是在模型类中未检测到行的部分插入“无行”实体,该部分用于处理数据更新 有许多方法可以实现这一点,例如,将名称/标题字段设置为实体内的已知状态消息或标志。插入后,您可以在CellForRowatineXpath委托方法中检测到“无行”实体,并插入替代表单元格以显示消息
在刷新该部分的数据之前,只需删除“no rows”实体。而不是使用tableview数据源获取所需的UI,您应该将“no rows found”消息添加到tableview标题中。我在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必须不透明才能隐藏标签。或者需要根据行数切换标签的隐藏属性。与其使用tableview数据源获取预期的UI,不如将“未找到行”消息添加到tableview标题中?如果表视图中只有一个部分,这是最好的方法。请参阅下面我的方法以了解更多信息sections@Rog这是一个完美的答案。在ViewWillDisplay中,如果行数为0,我将加载一个表视图标题。不幸的是,由于您没有将此作为答案输入,我无法选择它,但它(在我看来)是最干净和最好的答案。非常感谢。我很高兴它对你有用。我把它添加为一个答案,这样以后其他人可以很容易地找到它,所以下次你来的时候可以随意标记它为正确的。这是最干净、最好的答案。非常感谢!!我喜欢这个声音。您是说您要注意可用的行数,然后有条件地显示/隐藏tableview标题?或者总是显示页眉,只需将其文本更改为“未找到行”?Andy-您也可以使用页脚。如果我想显示代表“未找到数据”的全屏图像,我们怎么做?@Satyam您的工作是什么?我相信我也有类似的问题。为什么要投反对票?我只是提供了一个工作解决方案来处理多个部分!这不是一个好的解决方案,因为您无法使用内置的
UIRefreshControl
正确地子类化UIViewController
。最好使用视图控制器包含来嵌入表视图控制器子类,并在容器视图控制器中处理空视图。@amb这是一个可能的解决方案……op没有请求使用下拉刷新功能……在我的OPI洋葱中,包含太多了。谢谢您的评论。您完全正确,但是当您必须显示空表视图消息时,同时使用UITableViewController
和UIRefreshControl
是非常常见的。
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];