Search code examples
iosswiftuisearchbaruisearchcontrolleruinavigationitem

Unable to add UISearchController's search bar into navigationbar and delegate methods not getting called


I want to achieve something very simple: a search bar in the navigation bar, with a Cancel button that shows when the bar is activated.

I am using a UISearchController, and currently I have the following:

override func viewDidLoad() {
  super.viewDidLoad()
  ...

  let searchController = UISearchController(searchResultsController: nil)
  searchController.searchResultsUpdater = self
  searchController.delegate = self
  searchController.searchBar.delegate = self
  searchController.hidesNavigationBarDuringPresentation = false
  searchController.searchBar.sizeToFit()
  self.navigationItem.titleView = searchController.searchBar
  self.definesPresentationContext = true
}

The search bar shows. However, if I focus on it no Cancel button is shown, and no delegate methods are called whatsoever. That is, no methods in the UISearchResultsUpdating, UISearchControllerDelegate, or UISearchBarDelegate protocols are called, although I've set self to respond to all of them.

If I put the following line into viewDidLoad, the delegate methods start to function:

self.navigationItem.searchController = searchController

However, then I can't put the search bar inside the navbar. It's shown under the navbar instead.

I've searched extensively in SO but nothing seems to work for me. I may be missing something obvious here - how can I make it work? Thanks!


Solution

  • Just define UISearchController as property then everything working fine.

    I have tested below in the sample project.

      class ViewControllerName: UIViewController{
           let searchController = UISearchController(searchResultsController: nil)
    
            override func viewDidLoad() {
                super.viewDidLoad()
                let search = UISearchController(searchResultsController: nil)
                self.navigationItem.searchController = search
                self.navigationItem.searchController!.searchBar.delegate = self
                self.navigationItem.searchController!.searchResultsUpdater = self
                self.navigationItem.searchController?.searchBar.showsCancelButton = true
            }
    
           func searchBarTextDidEndEditing(_ searchBar: UISearchBar) {
                print("Called")
            }
    
            func updateSearchResults(for searchController: UISearchController) {
                print("Called")
            }
        }
    

    Hope it will work for you.