I had the same problem and found a solution.
The trick is not to give searchDisplayController
to call -setActive:animated:
anywhere, but in -viewWillDisappear
. Thus, you should make your view controller a delegate from searchBar
(to catch the cancel button) and lay the hidden button in the background when searchDisplayController
become active (to capture taps on an empty screen space).
In your view, the controller implements 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]; }
source share