Prevent a UISearchDisplayController from hiding the navigation bar

49,015

Solution 1

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).

Solution 2

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.

Solution 3

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

Solution 4

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].

Solution 5

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
Share:
49,015
hadronzoo
Author by

hadronzoo

Updated on February 15, 2020

Comments

  • hadronzoo
    hadronzoo over 4 years

    Whenever a user begins editing a UISearchDisplayController's search bar, the search controller becomes active and hides the view's navigation bar while presenting the search table view. Is it possible to prevent a UISearchDisplayController from hiding the navigation bar without reimplementing it?

  • gyozo kudor
    gyozo kudor over 13 years
    This is a lot simpler than the accepted answer. It worked for me as well.
  • Jan Aagaard
    Jan Aagaard over 13 years
    How did you do figure this out? I would like to change the behavior of the search, so that it keeps the table view dimmed until the user clicks on the search button, and your debugging solutions seems like a really elegant way to achieve this.
  • Mr. Míng
    Mr. Míng over 12 years
    Great, this is the best answer!
  • titaniumdecoy
    titaniumdecoy over 12 years
    The navigation bar slides up and down again when the user focuses on the text field. With animated:NO, it pops back into place. Both alternatives look bad.
  • malhal
    malhal almost 12 years
    I read all the proposed solutions and this was by far the simplest and the best.
  • richy
    richy almost 12 years
    I got: *** Assertion failure in -[UISearchDisplayController setActive:animated:] when hitting the cancel button.
  • richy
    richy almost 12 years
    Fixed this by calling [self.searchDisplayController setActive:NO animated:NO]; in - (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar
  • joerick
    joerick almost 12 years
    Hmm. It's possible this no longer works with current iOS versions.
  • Sylverb
    Sylverb over 11 years
    This is preventing some things to work correctly (like search scope or editable tableview)
  • Adriana
    Adriana over 11 years
    Agreed, this is the simplest solution. Just for completion: if you're using a xib, then select the search display controller, tap the identity inspector and change the class to MySearchDisplayController.
  • paiv
    paiv about 11 years
    Have you tried navigating to detail controller from results and back? This breaks views layout for me. iOS 6.1
  • Gajendra K Chauhan
    Gajendra K Chauhan almost 11 years
    not working for me.I've added but not found searchContentsController
  • Teofilo Israel Vizcaino Rodrig
    Teofilo Israel Vizcaino Rodrig over 10 years
    Definitively this is the solution
  • Irina
    Irina over 10 years
    this doesn't work when you have a detail view you want to show. once clicks back from the detail view the search bar slides under the navbar.
  • Irina
    Irina over 10 years
    this should be the answer. accepted answer doesn't fix the bug when you have a detail view.
  • Fateh Khalsa
    Fateh Khalsa over 10 years
    USE THIS ANSWER! This is fully functional, and Does Not have the detail view bug that the accepted answer has. Tested working in iOS 6/7.
  • stigi
    stigi over 10 years
    Thanks guys for the responses. Let's ping @hadronzoo, shall we? :)
  • Mike Sprague
    Mike Sprague over 10 years
    This worked for me with iOS 7 on the iPad. However, I added some code that makes it only return nil when the search display controller is calling it & it's on the ipad, otherwise it behaves normally. pastebin.com/6pJ2WWsy
  • mkko
    mkko over 10 years
    Anyone else get this exception: [<__NSArrayI 0xa6b82a0> valueForUndefinedKey:]: this class is not key value coding-compliant for the key colorMatrix. I'm using this on iPhone 7.0.3. @stigi's solution throws this as well.
  • jakenberg
    jakenberg over 10 years
    @mkko in iOS7, there's a property that you can set on UISearchDisplayController called displaysSearchBarInNavigationBar
  • mkko
    mkko over 10 years
    @jsksma2 Thanks, but I know of it and it's not really serving my purpose. displaysSearchBarInNavigationBar replaces the toolbar with its own class and I couldn't find a way to replace the title temporarily with a label. I was looking for a toolbar similar to Apple Maps and had to make one of my own (a UIView with buttons mimicing bar button items).
  • Matt Hudson
    Matt Hudson about 10 years
    Thank goodness for this post. I looked through several to no avail. This worked fantastic to prevent iOS 7 from janking up my UISearchDisplayController and UISearchBar animations.
  • Richie Hyatt
    Richie Hyatt almost 10 years
    worked for me by just adding part of this:-(void)viewDidLayoutSubviews { [self.navigationController setNavigationBarHidden:NO animated:NO]; // don't hide navigation bar when user taps the search bar }
  • Admin
    Admin almost 10 years
    Nice answer! But i had to add self.searchContentsController.edgesForExtendedLayout = UIRectEdgeBottom; for iOS 7
  • stigi
    stigi over 9 years
    @SebastianKeller yes, actually the answer is from 2010. That's way before iOS 7 & edgesForExtendedLayout :)
  • Admin
    Admin over 9 years
    @stigi: i know the answer is some years old, I just wanted to leave a hint if somebody else struggles with this on iOS 7 :)
  • Giorgos Ath
    Giorgos Ath over 9 years
    That doesn't really fix the problem. It does not hide the nav bar but if you have some scope bars below, then trying to tap on a scope bar makes search display controller resign first responder (scope bars now are bellow black semi-dimmed view for hiding the tableview behind...). Must find way to layout all views again... :(
  • Saleh Masum
    Saleh Masum over 9 years
    I subclassed UISearchDisplayController and set the subclass from storyboard. But the overridden method never gets called.
  • Javier Giovannini
    Javier Giovannini over 9 years
    This is the right answer, but with the stigi code (below).
  • heading_to_tahiti
    heading_to_tahiti over 9 years
    This is the correct answer for iOS 8 UISearchController!!
  • avance
    avance over 8 years
    I was having a similar problem, my navigation bar was disappearing when the keyboard appeared. Using the last 2 methods of the above code fixed it.
  • Vaibhav Jhaveri
    Vaibhav Jhaveri over 8 years
    Any solution for that ?
  • Khant Thu Linn
    Khant Thu Linn about 8 years
    I still need to push. [self.navigationController pushViewController:[iFeedbackFormStyle2VC loadFromNib] animated:YES]; But if it is empty, i can't push. how shall i do?
  • joerick
    joerick about 8 years
    @KhantThuLinn use [super navigationController] instead of self.navigationController
  • Boris Nikolic
    Boris Nikolic over 7 years
    This should be accepted answer. Works on iOS 8 for UISearchController.
  • ghostatron
    ghostatron over 7 years
    Can't decide if I'm amazed or horrified, but this worked. The stigi answer was close, but when I tapped into the search bar, the thing would still slide up BEHIND my nav bar (i.e. I could type and have the search "work", but I couldn't see the text).
  • manmal
    manmal over 7 years
    This API is available since iOS 8.0
  • Goppinath
    Goppinath over 7 years
    Ya, it is available since iOS 8.0.
  • New-Learner
    New-Learner about 7 years
    This is the simple solution