I encountered the same issue, and noticed that searchDisplayControllerDidEndSearch
was being called twice. The first time, the superview of self.searchDisplayController.searchBar
is the UITableView
, and the second time it's still a UIView
.
With the accepted answer, I worry about unintended consequences or unneeded overhead from re-inserting the subview every time the search bar is double-tapped, and I also worry about it breaking with future iOS versions. Fortunately, we can take advantage of the superview strangeness like this:
- (void)searchDisplayControllerDidEndSearch:(UISearchDisplayController *)controller {
if (self.tableView != self.searchDisplayController.searchBar.superview) {
[self.tableView insertSubview:self.searchDisplayController.searchBar aboveSubview:self.tableView];
}
}
If I had to guess what was happening, the UISearchBar
is automatically creating a temporary UIView
as its superview when it's active – this is the view seen when the search is being performed. While the UISearchBar
is being dismissed, the superview gets set back to be the UITableView
it had before, unless it gets dismissed so quickly that it was never properly initialized, in which case it cleans up improperly and the UITableView
never gets the UISearchBar
back as its child.
This solution still isn't ideal, and I think Apple must be doing something different in its own apps because their search bar UX feels a bit better. I think it would be better not to handle the second tap in the first place until the UISearchBar
was ready. I tried using the other UISearchBarDelegate
methods to do this, but I couldn't find an appropriate hook to override the current behavior.