2012-09-01 53 views
7

我已经实现了一个使用UITableViewController/UITableView和Core Data的iPhone应用程序。此外,我使用NSFetchedResultsController来管理表格数据。这一切都非常简单,并且效果很好。然后我决定当没有找到/检索到行时,我应该在UITableView中显示一条消息。经过研究,似乎做到这一点的最好方法(也许是唯一的方法)是返回一个包含该消息的“虚拟”单元。但是,当我这样做时,我从运行系统中得到一个令人厌恶的图表,它抱怨(并且正确地)关于数据不一致:“无效的更新:无效的部分数量。表格视图中包含的部分数量...”。下面是相关的代码:从类似的问题在核心数据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发展,我想学习的最佳实践)。谢谢。

+2

而不是破解tableview数据源以获得预期的UI为什么不添加“找不到行”消息到tableview头? – Rog

+0

@Rog有用的提示。 +1 –

+0

如果在表格视图中只有一个部分,这是最好的方法。看到我的方法下面的多个部分 – Brett

回答

12

而不是破解tableview数据源来获得预期的UI,你应该添加“找不到行”消息到tableview标题。

+0

这是最干净和最好的答案。非常感谢!! – user1092808

+0

我喜欢这样的声音。你是说你注意可用的行数,然后有条件地显示/隐藏tableview标题?或者始终显示标题并将其文本更改为“找不到行”? –

+0

标题栏中的搜索栏不起作用 – Andy

1

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

UIViewControllerUITableView组成(所述控制器中的数据源和用于您的表的委托),并通过显示在空白行消息的UILabel(或包含一个UILabel一个UIView)。

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

这种方法可能是艰苦的,但我认为这是很好的避免黑客NSFetchResultsController和数据源。此外,你可以完全控制你的空信息的位置。

由于@Rog建议您也可以使用表格视图标题来显示该消息。根据你喜欢的。

希望它有帮助。

+0

这不是一个好的解决方案,因为你不能使用UITableViewController内建的UIRefreshControl正确地继承UIViewController。最好使用视图控制器包含来嵌入表视图控制器子类并处理容器视图控制器中的空视图。 – amb

+0

@amb这是一个可能的解决方案...操作系统没有要求使用下拉菜单来刷新功能......在我的观点中,遏制措施太多了。谢谢你的评论。 –

+0

嗯,你是绝对正确的,但是当你必须显示一个空的表格视图消息时,同时使用“UITableViewController”和“UIRefreshControl”是非常常见的。 – amb

1

的另一种方法,这是我以前使用时,可将“无行”实体在没有行已在您的模型类被检测到的部分,它处理的数据使用核心数据管理更新你更新。

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

在刷新该部分的数据之前,只需删除'no rows'实体。

+0

为什么选择投票?我只是提供了一个工作解决方案来处理多个部分! – Brett

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

相关问题