2

I have a UISearchController in the navigation bar and it worked fine until now.

Only on iOS 9 the search bar refuse to be the first responder after the controller is loaded.

The code in viewDidLoad:

self.searchController = ({
        let controller = UISearchController(searchResultsController: nil)
        controller.searchResultsUpdater = self
        controller.delegate = self

        controller.dimsBackgroundDuringPresentation = false

        let ownSearchBar = controller.searchBar
        ownSearchBar.searchBarStyle = .Default
        ownSearchBar.barStyle = UIBarStyle.Black
        ownSearchBar.placeholder = NSLocalizedString("Search",  comment: "Search")
        ownSearchBar.showsCancelButton = true
        ownSearchBar.sizeToFit()
        ownSearchBar.delegate = self

        controller.searchBar.delegate = self
        controller.hidesNavigationBarDuringPresentation = false

        self.navigationItem.titleView = controller.searchBar
        self.navigationItem.hidesBackButton = true
        self.navigationController?.navigationBar.sizeToFit()


        return controller

    })()

The code in viewDidAppear:

override func viewDidAppear(animated: Bool) {
    super.viewDidAppear(animated)

    self.searchController.active = true
    self.searchController.searchBar.text = state.term
    self.segmentedControl.selectedSegmentIndex = state.searchType
}

And my code in didPresentSearchController:

extension SearchController :  UISearchControllerDelegate {
func didPresentSearchController(searchController: UISearchController){
    self.searchController.searchBar.becomeFirstResponder()
    xButtonWasPressed = true
}

}

Please help me find why only in iOS 9 the search bar don't get the focus

Jay Bhalani
  • 4,142
  • 8
  • 37
  • 50
Deano
  • 21
  • 1
  • 3

3 Answers3

3

The same problem for me. Worked well on iOS 8 but stopped working on iOS 9.

The bug is that in didPresentSearchController: method should be the SearchController already loaded but it is not.

So we need to get some delay to load it. My ugly but working solution is

 func didPresentSearchController(searchController: UISearchController) {

    UIView.animateWithDuration(0.1, animations: { () -> Void in }) { (completed) -> Void in

         searchController.searchBar.becomeFirstResponder()
    }
}

It is really important to have have becomeFirstResponder() in completed part of this method because it is the part when the SearchController is loaded

Hope it helps!

Jiří Zahálka
  • 8,070
  • 2
  • 21
  • 17
2

Helpful things...

  1. In viewDidLoad set self as delegate of the search bar searchController.delegate = self

  2. In viewDidAppear set self.searchController.isActive = true. If you do it in viewWillAppear it might not work without a delay

  3. Use the UISearchControllerDelegate method to make the keyboard active


    func presentSearchController(_ searchController: UISearchController) {
        DispatchQueue.main.async {
                searchController.searchBar.becomeFirstResponder()
            }
    }
}

NOTE: There's a method called didPresentSearchController which you'd think would be the one to use, but that only fires if the system automatically presents the search bar.

Joe
  • 343
  • 2
  • 11
0

Use the following code:

override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)            
        self.countrySearchBar.becomeFirstResponder()
    }

Here "countrySearchBar" is the outlet to your searchBar.

Please check my GitHub link to test sample project:

https://github.com/k-sathireddy/SearchDisplayControllerSample

KSR
  • 1,699
  • 15
  • 22