Search code examples
iosuisearchcontroller

Using UISearchController on a pushed view


I've successfully implemented a UISearchController in my app. I set it up like this in the viewDidLoad method of the view I want to use it in:

_profileSearchView = [self.storyboard instantiateViewControllerWithIdentifier:@"profileListView"];
[_profileSearchView initSearchController];
self.navigationItem.titleView = _profileSearchView.searchController.searchBar;

the initSearchController method initializes the search controller which is a property of the _profileSearchView and resides in _profileSearchView:

- (void) initSearchController {
    _searchController = [[UISearchController alloc] initWithSearchResultsController:self];
    _searchController.delegate = self;
    _searchController.hidesNavigationBarDuringPresentation = NO;

    _searchController.searchBar.delegate = self;
    _searchController.searchBar.searchBarStyle = UISearchBarStyleMinimal;
    _searchController.searchBar.showsCancelButton = YES;
    _searchController.searchBar.frame = CGRectMake(self.searchController.searchBar.frame.origin.x, self.searchController.searchBar.frame.origin.y, self.searchController.searchBar.frame.size.width, 44.0);
}

This works fine if I use it in a navigation controller's root view. But if I push a view and try to it use it there, the search controller doesn't become active and this error shows up in the console:

Warning: Attempt to present <UISearchController: 0x7fb113605220> on <RootViewController: 0x7fb11318a6d0> whose view is not in the window hierarchy!

The RootViewController it's complaining about is the root view which I pushed from. Why is this only working in the root view?

UPDATE: The root view controller has self.definesPresentationContext = YES; (which the pushed view also has), and when I removed that from the root view, the search controller works on the pushed view. Unfortunately that also breaks some other things so I need to leave it in. So how can I allow both the root and pushed views to each have a separate functioning search controller?


Solution

  • The issue was being caused by both the root and pushed view having self.definesPresentationContext = YES;. The solution was to add this:

    - (void) viewWillDisappear:(BOOL)animated {
        [super viewWillDisappear:animated];
        self.definesPresentationContext = NO;
    }
    

    And make sure it is YES when the view appears:

    -(void) viewWillAppear:(BOOL)animated {
        self.definesPresentationContext = YES;
    }
    

    in the root view. The root view was still able to properly push search results from its own search controller, and so was the pushed view.