【问题标题】:Reloading UITableView behind UISearchDisplayController在 UISearchDisplayController 后面重新加载 UITableView
【发布时间】:2011-04-08 12:28:55
【问题描述】:

我遇到了一个我无法弄清楚的非常奇怪的现象。我有一个管理 UITableView 的 UITableViewController。很简单。我还有一个 UISearchDisplayController 用于搜索表视图的内容。搜索功能将能够删除表格视图显示的内容项目。因此,如果用户选择删除他们在搜索时找到的项目之一,我不仅要重新加载 UISearchDisplayController 的表视图,还要重新加载 UITableViewController 的表视图。当我这样做时,常规表格视图的部分会弹出并显示在 UISearchDisplayController 上方。这真的很奇怪。我认为最好的解释方式是用图片:

如果你们中的任何人知道可能导致此问题的原因或知道解决方法,那就太好了。

【问题讨论】:

标签: ios uitableview reload uisearchdisplaycontroller behind


【解决方案1】:

再次更新

事实证明,如果表格的标题在后台重新加载,无论如何它都会出现在搜索控制器的前面。

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

已更新 - 下面的原始答案

在我的例子中,我使用了两个 fetchedResultsController,一个用于主 tableview,一个用于搜索。

我发现在添加部分标题时阻止动画可以防止这个错误。因此,虽然 searchDisplayController.active 我只是禁用了部分更改的动画。请参阅下面的代码。

- (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 中的标题。它是主表视图的标题,由于某种原因,它被添加到视图层次结构中的搜索表视图上方。

我通过在 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 上重新加载数据以便在后台看到它,节标题仍然漂浮在变暗区域的前面。

有人对此有更好的解决方案吗?当数据被 UISearchDisplayController 覆盖时重新加载时,对于 viewForHeaderInSection 和 titleForHeaderInSection 来说,这似乎是一个合法的错误。

对我来说最简单的答案是尝试覆盖搜索视图,这样您就看不到背景表。但这带走了应用程序的“Appleness”。

【讨论】:

    【解决方案2】:

    我们的解决方案是执行以下操作。它只在 iOS 7 中测试过:

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

    【讨论】:

      【解决方案3】:

      我最近也遇到了这个问题...我决定的方法是在暂停的串行调度队列中对主 tableView 的更新进行排队,直到 UISearchDisplayController 隐藏 searchResultsTableView。我可能会认为这是一个错误,因为如果 searchResultsTableView 已接管该层,则部分标题不应通过主 tableView 显示。

      【讨论】:

        【解决方案4】:

        我在 iOS 7 中通过仅重新加载基础表中的可见行来解决此问题。

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

        【讨论】:

        • 这对我有用。我有一个部分每秒重新加载,导致标题显示在我的 searchtableview 顶部。出于某种原因,重新加载可见的内容,而不是指定 indexPaths 本身是有效的。绝对是一个错误。
        • 这只有在底层数据模型没有改变的情况下才有效。
        【解决方案5】:

        修复它..

        在 viewDidLoad 中添加以下行

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

        这已经帮我解决了...

        【讨论】:

          【解决方案6】:
          [self.searchDisplayController.searchResultsTableView reloadData];
          

          【讨论】:

            【解决方案7】:

            因为使用了UITableViewControllerself.viewUITableViewController 中的TableViewSearchDisplayControllerContainerView 添加到UITableViewControllerself.view。只需使用UIViewcontroller

            【讨论】:

              【解决方案8】:

              我的解决方案是避免在显示搜索结果时重新加载表格,然后在搜索结果消失时重新加载。

              我必须在 UITableView reloadData 上设置一个符号断点,以查找所有导致节标题在搜索表顶部重绘的重新加载调用。

              【讨论】:

                【解决方案9】:

                希望您现在已经弄清楚了,但以防万一有人偶然发现这个问题:这可能是因为您的 UITableViewController 是搜索表和主表的数据源/委托。也就是说,大概您对两个表视图执行相同的 UITableViewDelegate/DataSource 方法,并且您为两个表返回相同的节标题。确保您单独处理搜索结果表:

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

                【讨论】:

                • 这很令人惊讶,但真正的问题是,来自后台 UITableView 的实际节标题显示在 UISearchDisplayController 的 UITableView 上方。在搜索结果中滚动时,背景部分标题显示为固定的,随着搜索结果在其后面上下移动而浮动在搜索结果上方。
                • 我看到了同样的东西——下面表格中的浮动标题。我们可以通过在某些地方调用 [self.searchDisplayController.searchResultsTableView reloadData] 来解决 iOS 6 中的问题,但它在 iOS 7 中不起作用。
                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 2013-06-25
                • 2011-08-26
                • 1970-01-01
                • 1970-01-01
                • 2013-04-07
                • 2013-07-10
                相关资源
                最近更新 更多