swiftuitextfielduisearchcontrollerbecomefirstresponder

becomeFirstResponder does not work in viewWillAppear


I'm using a UISearchController in my navigationItem.titleView.

The goal here is I can type in my search term & when I tap search I will be pushed to a new UIViewController. When I return to the previous UIViewController I want the UITextField keyboard visible with the cursor next to my previously typed text.

I am calling this in viewWillAppear but it's not displaying the keyboard. My UISearchController is updated in terms of design, and my text that I had typed in is visible, but I have to tap on the UITextField again to display the keyboard and show the cursor.

I have also tried this in viewDidAppear and it's the same experience.

UPDATE:

When I call perform selector in viewDidAppear, the keyboard shows for me.

Here is what I have tried:

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        
        // A check to see if I need to display the keyboard.
        if hasSearchedText {
            DispatchQueue.main.async {
                self.searchController?.searchBar.perform(#selector(self.becomeFirstResponder), with: nil, afterDelay: 0.1)
            }
        }
    }

    override func viewWillAppear(_ animated: Bool) {
            super.viewWillAppear(animated)
                                
            // I've tried removing this & moving it to viewDidAppear but same result.
            searchController?.isActive = true
            
            searchController?.searchBar.showsCancelButton = true
            
            let textFieldInsideSearchBar = searchController?.searchBar.value(forKey: "searchField") as? UITextField
            
            if let typedValue = UserDefaults.standard.value(forKey: "xyz") as? String {
                textFieldInsideSearchBar?.text = typedValue
                
                // resetting this value
                UserDefaults.standard.removeObject(forKey: "xyz")
                UserDefaults.standard.synchronize()
            }
            textFieldInsideSearchBar?.tintColor = // color
            textFieldInsideSearchBar?.layer.borderColor = // color
            textFieldInsideSearchBar?.layer.borderWidth = 2.0
            textFieldInsideSearchBar?.layer.cornerRadius = 8.0
            textFieldInsideSearchBar?.textColor = // color
            textFieldInsideSearchBar?.font = // font
    }

Solution

  • You need to call becomeFirstResponder on search bar on next run loop like this:

    override func viewDidAppear(_ animated: Bool) {
           super.viewDidAppear(animated)
    
           DispatchQueue.main.async {
               self.searchController.searchBar.becomeFirstResponder()
           }
    }