inorganik inorganik - 4 months ago 44x
iOS Question

Using UISearchController on a pushed view

I've successfully implemented a

in my app. I set it up like this in the
method of the view I want to use it in:

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

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

- (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?


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.