5
votes

In my app, I used to have a search bar in the header view of my table view. However, I have added a search bar button item, and when a user taps it, I want a search bar to animate across the navigation bar, and the user should be able to search. This is kind of like the search bar in the Twitter iOS app. here is the code for my UISearchController:

self.searchController = ({
        let controller = UISearchController(searchResultsController: nil)
        controller.searchResultsUpdater = self
        controller.hidesNavigationBarDuringPresentation = true
        controller.dimsBackgroundDuringPresentation = false
        controller.searchBar.sizeToFit()
        //self.tableView.tableHeaderView = controller.searchBar
        self.definesPresentationContext = true
        controller.searchBar.returnKeyType = .Search
        controller.searchBar.delegate = self

        return controller

    })()

Here is how my UINavigationBar looks like right now: enter image description here

How would I go about doing this?

1
I answer exactly this question here stackoverflow.com/questions/32259863/…Victor Sigler
@VictorSigler, I looked at your answer to a similar question. I actually want my search bar to appear in the same view controller as the uibarbuttonitem. So, how would I do this in an IBAction? I have tried doing this by setting the navigation bar's titleView to be the search bar in the barbuttonitem's method, but it didn't work.Rehaan Advani

1 Answers

7
votes

You're almost there. You need to do four things:

  1. searchController.hidesNavigationBarDuringPresentation = false
  2. navigationItem.titleView = searchController.searchBar
  3. hide all the current UIBarButtonItems you have in the navigation bar
  4. searchController.searchBar.becomesFirstResponder()

That is, you setup your UISearchController so it doesn't hide the navigation bar, as the UISearchBar is gonna be displayed there.

Then, when your IBAction runs, you do something like:

navigationItem.hidesBackButton = true
navigationItem.titleView = searchController.searchBar
navigationItem.rightBarButtonItem = nil
searchController.searchBar.becomeFirstResponder()

That guarantees the UISearchBar will use the entire UINavigationBar when it becomes the first responder. You also get the UISearchBar animation, which does a good job in hiding the unanimated removal of the UIBarButtonItems.

You will need to implement the UISearchBarDelegate (or if you prefer UISearchControllerDelegate) to restore the original navigation bar state once the user is done with the search.

One very important detail is that in order for your UISearchBar to be editable in the titleView, no other view controller can be set with definesPresentationContext = true at the time yours is pushed.