Prevent a UISearchDisplayController from hiding the navigation bar

I just debugged a bit into UISearchDisplayController and found that it's calling a private method on UINavigationController to hide the navigation bar. This happens in -setActive:animated:. If you subclass UISearchDisplayController and overwrite this method with the following code you can prevent the navigationBar from being hidden by faking it to be already hidden.

- (void)setActive:(BOOL)visible animated:(BOOL)animated;
{
    if(self.active == visible) return;
    [self.searchContentsController.navigationController setNavigationBarHidden:YES animated:NO];
    [super setActive:visible animated:animated];
    [self.searchContentsController.navigationController setNavigationBarHidden:NO animated:NO];
    if (visible) {
        [self.searchBar becomeFirstResponder];
    } else {
        [self.searchBar resignFirstResponder];
    }   
}

Let me know if this works for you. I also hope this won't break in future iOS versions... Tested on iOS 4.0 only.


The simplest solution and no hacks.

@interface MySearchDisplayController : UISearchDisplayController

@end

@implementation MySearchDisplayController

- (void)setActive:(BOOL)visible animated:(BOOL)animated
{
    [super setActive: visible animated: animated];

    [self.searchContentsController.navigationController setNavigationBarHidden: NO animated: NO];
}

@end

The new UISearchController class introduced with iOS 8 has a property hidesNavigationBarDuringPresentation which you can set to false if you want to keep the navigation bar visible (by default it will still be hidden).


The above answers didn't work quite right for me. My solution is to fool the UISearchDisplayController into thinking there wasn't a UINavigationController.

In your view controller, add this method

- (UINavigationController *)navigationController {
    return nil;
}

This had no untoward side effects for me, despite seeming like a really bad idea... If you need to get at the navigation controller, use [super navigationController].


Since iOS 8.0 the same behavior can be achieved by setting the UISearchController's self.searchController.hidesNavigationBarDuringPresentation property to false.

The code in Swift looks like this:

searchController.hidesNavigationBarDuringPresentation = false