I had the same problem and found a solution.
The trick is not to give searchDisplayController
to call -setActive:animated:
anywhere but in -viewWillDisappear
.
So you should make your view controller a delegate of the searchBar
(to catch taps on "cancel" button) and lay a hidden button on background when searchDisplayController
did become active (to catch taps on empty screen space).
In your view controller implement these methods:
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
[self.searchDisplayController setActive:NO animated:animated];
}
- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar
{
[self.navigationController popViewControllerAnimated:YES];
}
- (void)backgroundClicked:(id)sender
{
[self.navigationController popViewControllerAnimated:YES];
}
- (void)searchDisplayControllerDidBeginSearch:(UISearchDisplayController *)controller
{
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
[button addTarget:self action:@selector(backgroundClicked:) forControlEvents:UIControlEventTouchUpInside];
CGFloat searchBarHeight = controller.searchBar.frame.size.height;
button.frame = CGRectOffset(self.view.bounds, 0.f, searchBarHeight) ;
[self.view addSubview:button];
}