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