I'm working on a view with a search bar. When the search becomes active, the navigation bar should be animated out (i.e., like -[navigationController setNavigationBarHidden:animated:]
.
I've implemented this using UISearchDisplayController
, and it mostly does the right thing, except it's failing to hide the navigation bar. The view hierarchy is stacked like this:
UIWindow
+-> IIViewDeckController
+->UINavigationController
+->UITableViewController
I've initialized things like this:
- (void)viewDidLoad
{
UISearchBar *searchBar = [[UISearchBar alloc] init];
self.searchDisplayController = [[UISearchDisplayController alloc] initWithSearchBar:searchBar contentsController:self];
self.tableView.tableHeaderView = searchBar;
}
I've also tried using a different drawer controller to see if the problem is in IIViewDeckController, like this:
UIWindow
+-> MMDrawerController
+->UINavigationController
+->UITableViewController
Normally, UISearchDisplayController
should call -[UINavigationController setNavigationBarHidden:animated:]
from somewhere in -[UISearchDisplayController setActive:animated:]
. I've even tried creating a class derived from UISearchDisplayController
and overloading -[UISearchDisplayController setActive:animated:]
and manually hiding the navigation bar, like this:
- (void)setActive:(BOOL)visible animated:(BOOL)animated
{
[self.searchContentsController.navigationController setNavigationBarHidden:visible animated:animated];
[super setActive:visible animated:animated];
}
Update for clarity: this code does actually hide the navbar as expected, but it doesn't clear out views that are north of the search bar and I wind up with another view sitting on top of the status bar (which kinda makes sense, because while debugging through -[UISearchDisplayController setActive:animated:]
I found that it uses some private APIs to clear out refresh controllers when it hides the navbar. I think.
For some reason the navigation bar isn't hiding and I've been having a devil of a time trying to figure out why.
What could cause this behavior?
Update #2
Looks like I missed a view in the hierarchy, and it seems to be the culprit in some way (still not sure in what way, exactly). Here it is:
UIWindow
+-> MMDrawerController
+-> UINavigationController
+-> UITabBarController
+-> UITableViewController
It looks like UITabBarController
is the problem, and I should've known, because it's even mentioned here (How to combine TabBarController with Navigation Controller?) and it is in the docs, although not too prominently:
An app that uses a tab bar controller can also use navigation controllers in one or more tabs. When combining these two types of view controller in the same user interface, the tab bar controller always acts as the wrapper for the navigation controllers.
The answer, it seems to me is that the view hierarchy needs to be altered so that there is no UITabBarController (because using one would require it to be the root controller, which would force a total redesign of the app). It looks like the most viable alternative would be to use a UITabBar
without a UITabBarController
.