在UISearchDisplayController后面重新加载UITableView

我遇到了这个奇怪的现象,我不太明白。 我有一个UITableViewControllerpipe理一个UITableView。 很简单。 我也有一个UISearchDisplayController用于search表视图的内容。 searchfunction将能够删除表格视图显示的内容的项目。 因此,如果用户select删除search时find的项目之一,我不仅要重新加载UISearchDisplayController的表视图,而且还要UITableViewController的表视图。 当我这样做时,常规表视图的部分popup并显示在UISearchDisplayController上方。 真的很奇怪 我认为解释这个问题的最好方法是用一个图像:

http://img46.imageshack.us/img46/2818/screenshot20100905at140.png

如果你们中的任何一个知道什么可能导致这个问题或知道一个解决方法,这将是太棒了。

再次更新

事实certificate,如果表格的标题在后台重新加载,无论如何它都会在search控制器前面popup。

我通过禁用fetchedResultsController(将其设置为nil)并在需要search消失时再次延迟加载它来解决此问题。

更新 – 下面的原始答案

在我的情况下,我使用两个fetchedResultsControllers一个用于主桌面视图,另一个用于search。

我发现,添加节头时防止animation可以防止这个错误。 所以虽然searchDisplayController.active我只是禁用部分更改的animation。 看下面的代码。

- (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id <NSFetchedResultsSectionInfo>)sectionInfo atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type { if (!self.reordering) { UITableView *myTableView = controller == __fetchedResultsController ? self.tableView : self.searchDisplayController.searchResultsTableView; UITableViewRowAnimation animation; if (self.searchDisplayController.active) { animation = UITableViewRowAnimationNone; } else { animation = UITableViewRowAnimationFade; } switch(type) { case NSFetchedResultsChangeInsert: [myTableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:animation]; break; case NSFetchedResultsChangeDelete: [myTableView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:animation]; break; } } } 

原来的答案

另一个答案实际上并没有在自己的工作。 原因是,显示的标题不是searchDisplayController的tableview中的标题。 这是主表视图中的标题,由于某种原因被添加到视图层次结构中的search表视图之上。

我解决了这个问题,在searchDisplayController.active = YES的时候禁止更新主表。

在我的情况下,我正在使用一个懒惰的加载获取结果控制器,所以我这样做:

 - (void)searchDisplayController:(UISearchDisplayController *)controller didHideSearchResultsTableView:(UITableView *)tableView { [self.tableView reloadData]; } - (void)searchDisplayController:(UISearchDisplayController *)controller willShowSearchResultsTableView:(UITableView *)tableView { self.fetchedResultsController.delegate = nil; self.fetchedResultsController = nil; } 

但是,我仍然有问题,如果我想在主要的tableview reloadData,所以它在后台看到,节标题仍然漂浮在黑暗的地区前面。

有没有人有更好的解决scheme呢? 对于viewForHeaderInSection和titleForHeaderInSection来说,当数据被UISearchDisplayController覆盖的同时重新加载时,它似乎是一个合法的bug。

对我来说最简单的答案是尝试和重写search视图,所以你不能看到背景表。 但是,这远离了应用程序的“苹果性”。

我们的解决scheme是做到以下几点。 它只在iOS 7中testing过:

  1. viewForHeaderInSection ,如果self.searchDisplayController.active为YES,则返回nil
  2. didHideSearchResultsTableView ,当search表消失时,调用[self.tableView reloadData]重新加载标题

我最近碰到这个以及…我决定的方法是队列更新到暂停的串行调度队列中的主tableView,直到UISearchDisplayController隐藏searchResultsTableView。 我可能会认为这是一个错误,因为如果searchResultsTableView已经接pipe了该层,那么节标题不应该通过主tableView显示。

我在iOS 7中解决了这个问题,只重新加载了底层表中的可见行。

 - (void)searchDisplayController:(UISearchDisplayController *)controller didHideSearchResultsTableView:(UITableView *)tableView { [self.tableView reloadRowsAtIndexPaths:[self.tableView indexPathsForVisibleRows] withRowAnimation:UITableViewRowAnimationNone]; } 

修复..

在viewDidLoad中添加以下行

 searchDisplayController.searchResultsTableView.delegate = self; searchDisplayController.searchResultsTableView.dataSource = self; 

为我修好了…

 [self.searchDisplayController.searchResultsTableView reloadData]; 

因为使用UITableViewControllerself.viewUITableViewControllerTableViewSearchDisplayControllerContainerView被添加到UITableViewController SearchDisplayController 。 只要使用UIViewcontroller

我的解决scheme是避免重新加载表,如果search结果显示,然后重新加载任何时候search结果被解雇。

我不得不在UITableView reloadData上设置一个符号断点,以查找所有重新加载的调用,这些调用导致段标头在search表顶部重绘。

希望你已经明白了这一点,但以防万一有人绊倒这个问题:这可能是因为你的UITableViewController是search表的数据源/委托以及主表。 也就是说,大概你有两个表视图执行相同的UITableViewDelegate / DataSource方法,并且你为这两个表返回相同的节标题。 确保你分开处理你的search结果表:

 - (NSString *)tableView:(UITableView *)aTableView titleForHeaderInSection:(NSInteger)section { if (aTableView == [[self searchDisplayController] searchResultsTableView]) { return nil; } // Return a title appropriate for self.tableView here }