当 UISearchBar.becomeFirstResponder() 被调用时,键盘出现并立即消失

Keyboard is appearing and immediately disappearing when UISearchBar.becomeFirstResponder() is getting called

我在 navigationItem.searchController 中有 UISearchController,我想在用户从菜单中选择 "Search" 时使其成为焦点。 很快,当用户点击菜单中的 "Search" 选项 (UITableViewCell) 时,它会获取其中包含 searchController 的视图控制器并调用:

guard let navigationVC = presentingViewController as? UINavigationController else { return }
guard let documentsVC = navigationVC.topViewController as? DocumentsViewController else { return }
documentsVC.searchController.searchBar.becomeFirstResponder()

然后,UISearchBar 获得焦点,键盘出现然后立即消失,我 没有任何代码可以让它消失(比如 view.endEditing())。

1张GIF超过1000字:

在 viewDidLoad 方法中使您的搜索栏成为第一响应者。这将确保在聚焦搜索栏之前一切就绪。

所以,经过多次尝试,我找到了一些方法让它工作,但我确信有更优雅的方法来做到这一点,所以 如果有人认为他们有更好的方法,请post在这里,我可能会使用它并将您的答案标记为正确答案。

YourViewController 中创建函数 focusOnSearchBar():

func focusOnSearchBar() {
  let searchBar = searchController.searchBar
  if searchBar.canBecomeFirstResponder {
    DispatchQueue.main.async {
      searchBar.becomeFirstResponder()
    }
  } else {
    DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
      self.focusOnSearchBar()
    }
  }
}

它实际上做的是递归地使用自己并检查(每 0.1 秒)是否 searchBar.canBecomeFirstResponder这就是problematic/not优雅的东西。

然后,将此添加到 viewDidAppear():

if focusOnSearch {
  searchController.isActive = true
}

不要忘记为 UISearchControllerDelegate 添加扩展到 ViewController(当然,设置 searchController.delegate = self)并实现 didPresentSearchController(将由设置 searchController.isActive = true):

extension YourViewController: UISearchControllerDelegate {
  func didPresentSearchController(_ searchController: UISearchController) {
    if focusOnSearch {
      focusOnSearchBar()
    }
  }
}

现在你所要做的就是在prepare(for segue:sender:)中设置focusOnSearch = true

*注意:如果你想focusOnSearchBar 而你在[=25=的同一个viewController ], 只需设置:

 focusOnSearch = true
 searchController.isActive = true

它会自动运行。