54

How can I show a UISearchBar in the NavigationBar?

I can't figure out how to do this.

Your help is very much appreciated.

Brian
  • 14,610
  • 7
  • 35
  • 43
Samui
  • 1,384
  • 3
  • 14
  • 28

5 Answers5

86

To put searchBar into the center of navigationBar:

self.navigationItem.titleView = self.searchBarTop;

To put searchBar to the left/right side of navigationBar:

UIBarButtonItem *searchBarItem = [[UIBarButtonItem alloc] initWithCustomView:searchBar];
self.navigationItem.rightBarButtonItem = searchBarItem;
Borut Tomazin
  • 8,041
  • 11
  • 78
  • 91
  • 1
    I have the problem that on iPad the results are shown in a table view embedded in a popover, instead of in the frame of the original table view. Any solution to this? – Norbert Oct 05 '13 at 08:57
  • 2
    If I set it like this, the `searchDisplayController` doesn't show up anymore. The `cellForRowAtIndexPath:` method isn't called either. With `searchDisplayController.displaysSearchBarInNavigationBar` works but I can't use it because I'm supporting iOS 6 too... – jdev Mar 02 '15 at 22:57
  • 1
    This approach hides the title – Panos Nov 08 '16 at 18:20
  • self.navigationItem.titleView = searchBar if you you want it in centre this works – Saurav Oct 20 '17 at 11:38
20

As of iOS 7, the UISearchDisplayController supports this by default. Set the UISearchDisplayController's displaysSearchBarInNavigationBar = YES to get this working easily.

Per the documentation:

Starting in iOS 7.0, you can use a search display controller with a navigation bar (an instance of the UINavigationBar class) by configuring the search display controller’s displaysSearchBarInNavigationBar and navigationItem properties.

James Kuang
  • 10,710
  • 4
  • 28
  • 38
  • According the Apple's docs, it looks like we can't set the searchBar in the titleView. Am I right? Can you show us how you set the navigationItem of the searchDisplayController? Thank you – NLemay Sep 24 '13 at 18:01
  • 6
    I tried this but my search bar is in the middle of the screen! – Van Du Tran Oct 05 '13 at 16:49
  • 5
    The easiest way when using Storyboards is to drag a Search Bar and Search Display Controller out of the Utility Area into the bottom of the current scene inside Document Outline. After that just add `self.searchDisplayController.displaysSearchBarInNavigationBar = YES;` in viewdidload. You may want to show a cancel button or hide the backbutton while editing so this could be done in the delegate implementation. – Bohrnsen Oct 06 '13 at 19:59
  • 8
    This makes the search bar occupy the whole navigation bar, hiding any existing leftbar and rightbarbuttons. How can I still keep those? – fishinear Oct 25 '13 at 10:32
  • @fishinear, check out the answer i just posted on how to add a searchdisplaycontroller to your navigation while maintaining the left/right bar button items. – djibouti33 Nov 27 '13 at 21:10
  • @VanDuTran I had this issue when I assigned searchbar to tableview header, when I removed I've got another problem — search results table view shows only on first search. – Shmidt Mar 14 '14 at 16:51
12

As one commenter noted, using searchDisplayController.displaysSearchBarInNavigationBar = true ends up hiding any existing left/right bar button items.

I've found two different ways of adding a searchBar to a navigationBar using iOS7's new property on searchDisplayController.

1) Nib Based Approach

If you're using a .xib, you can set a User Defined Runtime Attribute for this value and for whatever reason, the leftBarButtonItem stays in tact. I have not tested it with a rightBarButtonItem.

enter image description here

2) Code (Timing Matters)

If you want to implement in code, timing seems to matter. It seems that you must add the searchBar to the navigationBar first, then set your barButtonItem.

- (void)viewDidLoad
{
    ...
    self.searchDisplayController.displaysSearchBarInNavigationBar = true;
    self.navigationItem.leftBarButtonItem = [UIBarButtonItem new];
    ...
}
djibouti33
  • 12,102
  • 9
  • 83
  • 116
  • 1
    I tried (1) in storyboard and it crashes. this class is not key value coding-compliant for the key displaysSearchBarInNavigationBar.' – Van Du Tran Mar 13 '14 at 01:19
  • You can do it in a StoryBoard, but you need to set it on the Search Display Controller, not on the View Controller; however, it doesn't preserve the right button item in my test, but it does put the search bar in the navbar. – Peter Apr 15 '14 at 20:49
  • 1
    You can use #2 with UIBarButtonItems setup in a StoryBoard that have a referencing outlet. Instead of [UIBarButtonItem new] above do: ```self.navigationItem.leftBarButtonItem = self.leftButton``` (where self.leftButton is the outlet for the left button). – Peter Apr 15 '14 at 20:53
  • 3
    It appears that SearchDisplayController had been deprecated since iOS 8.0. – fatuhoku Jul 01 '15 at 11:19
  • Ray Weinerlich has a good tutorial on this http://www.raywenderlich.com/113772/uisearchcontroller-tutorial – Grimxn Jan 13 '16 at 18:22
11

Check out Apple's UICatalog sample code. It shows how to use the new UISearchController in three different ways: modally, in nav bar, and below the navigation bar.

Steve Moser
  • 7,647
  • 5
  • 55
  • 94
  • 1
    These samples helped me incredibly much. Thank you! – Okhan Okbay Jul 06 '17 at 10:35
  • 1
    I took a break from iOS for a few years and missed lots of UIKit updates. This is so helpful. Apple really needs better organization of their docs. I have spent countless hours going through the WWDC vids/samples, searching the Documentation Archive, and I have never seen this. Thanks for sharing – hidden-username Nov 02 '18 at 21:26
  • 1
    Maybe I'm missing it, but it seems that the latest version only contains two examples, Default and Custom, neither of which has it in the nav bar :( – Ric Santos Apr 20 '20 at 01:03
2

Objective C code snippet for UISearchBar in NavigationBar

- (void)viewDidLoad {
    UISearchController *searchController = [[UISearchController alloc] initWithSearchResultsController:nil];
    
    if (@available(iOS 11.0, *)) {
        self.navigationItem.searchController = searchController;
    } else {
        self.navigationItem.titleView = searchController.searchBar;
    }
}

Read more here

yoAlex5
  • 29,217
  • 8
  • 193
  • 205