Cannot set searchBar as firstResponder

前端 未结 21 1829
别跟我提以往
别跟我提以往 2020-11-30 01:33

I have a searchBar I\'m setting in a tableviewcontroller. i\'ve referenced this similar question UISearchBar cannot become first responder after UITableView did re-appear bu

相关标签:
21条回答
  • Easy Swift3 variant:

    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()
    }
    

    It works ;-)

    0 讨论(0)
  • 2020-11-30 02:14

    Xcode 11.4, Swift 5.2

    If you just want the SearchBar to appear but not activate the TextField & keyboard. There is no need to dispatch it to the main thread.

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        searchController.isActive = true
    }
    

    If you want the TextField to activate with the keyboard, then you do need to call it on the main thread. There is no need to make the SearchController active, this happens automatically.

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

    This may depend on how you configure your SearchController. This is how I configure mine:

    // Defined in class
    let searchController = UISearchController(searchResultsController: nil)
    
    // Called in viewDidLoad
    navigationItem.searchController = searchController
    searchController.searchResultsUpdater = self
    searchController.searchBar.scopeButtonTitles = ["A", "B"]
    searchController.searchBar.delegate = self          
    searchController.obscuresBackgroundDuringPresentation = false
    
    0 讨论(0)
  • 2020-11-30 02:17

    Swift 5

    class ViewController {
        override func viewDidAppear(_ animated: Bool) {
            super.viewDidAppear(animated)
            // Only after viewDidAppear searchController can be activated
            searchController?.isActive = true
        }
    }
    
    extension ViewController: UISearchControllerDelegate {
        // didPresentSearchController not work for me
        func presentSearchController(_ searchController: UISearchController) {
            searchController.searchBar.becomeFirstResponder()
        }
    }
    
    0 讨论(0)
  • 2020-11-30 02:18

    I think there might be a cleaner solution. I found that the keyboard was sort of 'blipping' up and then back down when presented, and calling becomeFirstResponder in didPresentSearchController: was working, but the keyboard was coming in late, and the animation was a bit quirky.

    Wrapping my reload data method with a check for presentation made everyone happy:

    - (void)updateSearchResultsForSearchController:(UISearchController *)searchController
    {
        if (!searchController.isBeingPresented && !searchController.isBeingDismissed) {
            [self.collectionView reloadData];
        }
    }
    

    I found this by setting a breakpoint in resignFirstResponder. resignFirstResponder was being called from the reloadData, which in turn was called by updateSearchResultsForSearchController:. It turns out that updateSearchResultsForSearchController: is called during the presentation of the search controller. If you muck with the view hierarchy that the UISearchBar is in during this time, the search controller gets borked. My guess is that the reloadData call was causing the UICollectionReusableView header view to come out and go back into the view hierarchy and forcing the UISearchBar subview to resign first responder.

    Another symptom I saw was the the search term was not resetting to the middle of the search bar on cancel, which caused it not to present properly on future clicks.

    0 讨论(0)
  • 2020-11-30 02:19

    The function searchController.searchBar.becomeFirstResponder() must be called in the main thread and after searchController.active = true in the viewDidLoad method. Here're the full solution. It works on iOS 9.3

    override func viewDidAppear(animated: Bool) {
      super.viewDidAppear(animated)
      searchController.active = true
      Async.main {
        self.searchController.searchBar.becomeFirstResponder()
      }
    }
    
    0 讨论(0)
  • 2020-11-30 02:19

    Swift 5 solution:

    override func viewDidLoad() {
            super.viewDidLoad()
            definesPresentationContext = true
            searchController.delegate = self
        }
    
    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        searchController.isActive = true
    }
    
    extension ViewController: UISearchControllerDelegate {
     func didPresentSearchController(_ searchController: UISearchController) {
          DispatchQueue.main.async {[weak self] in
              self?.searchController.searchBar.becomeFirstResponder()
           }
      }
    }
    
    0 讨论(0)
提交回复
热议问题