11

I created a UISearchController in a table view controller. I segue to this table view controller using a push segue from another view controller. I want the keyboard to show up with the cursor in the search bar as soon as the table view controller is pushed.

I made the search controller active in the viewDidLoad method using

self.mySearchController.active = true

It does make the search controller active but this does not bring up the keyboard nor is the cursor placed in the search bar. I also tried

self.mySearchController.searchBar.becomeFirstResponder()

This line does not seem to have any effect.

How do I bring up the keyboard automatically/programmatically? Below is a more detailed version of my code

class PickAddressViewController: UITableViewController, UISearchResultsUpdating {

var searchText = ""

var mySearchController = UISearchController()

override func viewDidLoad() {
    super.viewDidLoad()

    self.mySearchController = ({
        let controller = UISearchController(searchResultsController: nil)
        controller.searchResultsUpdater = self
        controller.dimsBackgroundDuringPresentation = false
        controller.searchBar.sizeToFit()
        controller.searchBar.text = self.searchText

        self.tableView.tableHeaderView = controller.searchBar

        return controller
    })()

    self.mySearchController.active = true
    self.mySearchController.searchBar.becomeFirstResponder()
}
RookiePro
  • 633
  • 1
  • 9
  • 18

6 Answers6

7

BecomeFirstResponder is the way to go, but you should do it not in viewDidLoad. Look at following discussion for details - Cannot set searchBar as firstResponder

Community
  • 1
  • 1
Nikita Leonov
  • 5,684
  • 31
  • 37
  • 4
    Great! I tried the solution in that link and it works! For any other newbies like me, in addition to the code I wrote in my question above, you have to do the following: Make the view controller a UISearchControllerDelegate. While defining the search controller, write a line that says controller.delegate = self. Put the becomeFirstResponder line in the delegate function named 'didPresentSearchController' – RookiePro Jun 29 '15 at 01:37
5

Swift 5

  1. in viewDidLoad:
searchViewController.delegate = self
  1. in viewDidAppear:
searchViewController.isActive = true

This activates the SearchController

  1. Define a delegate method:
extension MyViewController: UISearchControllerDelegate {
    func didPresentSearchController(_ searchController: UISearchController) {
        DispatchQueue.main.async {
            searchController.searchBar.becomeFirstResponder()
        }
    }
}
Tung Fam
  • 7,899
  • 4
  • 56
  • 63
  • I'm trying this method but with a different approach. So I tap into my Search Controller, then from there will push to a new View Controller, and when I go back I want my keyboard to be visible. Right now everything looks to get called but my keyboard isn't visible. I have to tap into the UISearchController Search Bar again to make it visible. Any suggestions? – Luke Irvin Feb 12 '21 at 01:12
  • This works perfect and actually opens the keyboard once the viewcontroller is presented. – Ahmed Shendy Dec 10 '21 at 20:02
  • `searchViewController.isActive = true` should be called from main queue. Have a look at https://stackoverflow.com/questions/31274058/make-uisearchcontroller-search-bar-automatically-active/ – tanmoy Jul 18 '22 at 11:18
4

I also tried the suggestions listed in the link mentioned by Nikita Leonov. I needed to add make the class a UISearchControllerDelegate & UISearchBarDelegate and then it worked. I don't u

class PickAddressViewController: UITableViewController, UISearchControllerDelegate, UISearchBarDelegate, UISearchResultsUpdating {

    override func viewDidLoad() {
        super.viewDidLoad()

        self.mySearchController = ({
            controller.searchBar.delegate = self
        })()

        self.mySearchController.active = true
        self.mySearchController.delegate = self
    }

    func didPresentSearchController(searchController: UISearchController) {
        self.mySearchController.searchBar.becomeFirstResponder()
    }
    …
}
empedocle
  • 1,862
  • 1
  • 14
  • 25
3

Swift 3 solution in my case:

override func viewDidLoad() {
    super.viewDidLoad()
    navigationItem.titleView = mySearchController.searchBar
    mySearchController.searchResultsUpdater = self
    mySearchController.delegate = self

}

override func viewDidAppear(_ animated: Bool) {
    DispatchQueue.main.async {
        self.mySearchController.isActive = true
    }
}

func presentSearchController(_ searchController: UISearchController) {
    mySearchController.searchBar.becomeFirstResponder()
}
Vitya Shurapov
  • 2,200
  • 2
  • 27
  • 32
2
override func viewDidAppear(animated: Bool) {
    super.viewDidAppear(true)
    self.navigationItem.titleView = searchController!.searchBar
    dispatch_async(dispatch_get_main_queue(), {
        self.searchController?.active = true
        self.searchController!.searchBar.becomeFirstResponder()
    })
}

and this code

func presentSearchController(searchController: UISearchController) {
    searchController.searchBar.becomeFirstResponder()
}

make sure you give searchController?.delegate = self in viewDidLoad(). Tested on iOS 9.* device

anuraagdjain
  • 86
  • 2
  • 7
0

Besides doing what the other users suggested, I also did the following, and it worked:

searchController.definesPresentationContext = true

Natan R.
  • 5,141
  • 1
  • 31
  • 48