Reloading UITableView behind UISearchDisplayController

前端 未结 9 2105
南旧
南旧 2021-02-07 11:26

I\'ve run into this really strange phenomenon that I can\'t quite figure out. I have a UITableViewController that manages a UITableView. Pretty simple. I also have a UISearch

9条回答
  •  滥情空心
    2021-02-07 11:56

    UPDATED AGAIN

    As it turns out, if a table's header is reloaded in the background it pops in front of the search controller no matter what.

    I solved this by disabling the fetchedResultsController (setting it to nil) and letting it load lazily again when needed when the search disappears.

    UPDATED - Original answer below

    In my case I'm using two fetchedResultsControllers one for the main tableview and one for the search.

    I discovered that preventing animations when adding the section headers prevents this bug. So while searchDisplayController.active I simply disable the animation of the section change. see code below.

    - (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id )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;
            }
        }
    }
    

    ORIGINAL ANSWER

    The other answer doesn't actually work on it's own. The reason is, the header that is showing is not a header in the searchDisplayController's tableview. It's a header from the main tableview that for some reason is being added above the search table view in the view hierarchy.

    I solved this problem by disabling updates to the main tableview while searchDisplayController.active = YES.

    In my case I'm using a lazily loaded fetched results controller so I did it like this:

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

    However, I still have the problem that if I want to reloadData on the main tableview so it is seen in the background, the section headers still float in front of the darkened area.

    Does anyone have a better solution for this? It seems like a legitimate bug for viewForHeaderInSection and titleForHeaderInSection when data is reloaded while covered by a UISearchDisplayController.

    The simplest answer for me is to try and override the search view so you can't see the background table. But that takes away from the "Appleness" of the app.

提交回复
热议问题