使取消按钮和软件键盘自动出现在 viewDidLoad() 中

Causing cancel button and software keyboard to appear automatically in viewDidLoad()

注意:我已尝试使用 .becomeFirstResponder(),如上文 link 所示。我愚蠢地在我的第一个 post 中遗漏了这个细节。查看我的代码进行编辑。

我在自己专用的 viewController 中使用 UISearchBar(用于搜索栏的代码来自 Google,作为其 SDK 的一部分)。一旦应用进入 viewController,我希望键盘在没有用户干预的情况下立即出现,我不希望它消失。更重要的是,我希望取消按钮始终可见。

我已经知道如何使用 resignFirstResponder 使键盘消失。我尝试使用 .becomeFirstResponder() 没有效果。但是,查看 Whosebug、Google 和 Apple 的文档,我没有看到在没有用户干预的情况下让它出现的方法。

所有功能,例如 editingDidBegin() 都需要用户做一些事情。

这感觉很基本,但我一无所获。

private var resultsViewController: GMSAutocompleteResultsViewController?
private var searchController: UISearchController?
private var resultView: UITextView?

// tableview code for Google autocomplete
private var tableDataSource: GMSAutocompleteTableDataSource?

//不包括不相关的代码...

// 在 vi​​ewDidLoad() 中调用

func displaySearchBar(){

    let searchVerticalLocation = UIScreen.main.bounds.height-UIScreen.main.bounds.height+33
    resultsViewController = GMSAutocompleteResultsViewController()
    resultsViewController?.delegate = self
    //resultsViewController.becomeFirstResponder() doesn't work
    searchController = UISearchController(searchResultsController: resultsViewController)
    searchController?.searchResultsUpdater = resultsViewController
    let subView = UIView(frame: CGRect(x: 0, y: searchVerticalLocation, width: 350, height: 60))
    searchController?.searchBar.barTintColor = UIColor(red: 234/255.0, green: 93/255.0, blue: 0/255.0, alpha: 1.0)
    searchController?.searchBar.keyboardAppearance = .dark
    searchController?.searchBar.searchBarStyle = .prominent
    searchController?.searchBar.placeholder = "enter destination"
    searchController?.searchBar.isTranslucent = true
    searchController?.searchBar.leftAnchor.constraint(equalTo: subView.leftAnchor, constant: 100)
    searchController?.searchBar.rightAnchor.constraint(equalTo: subView.rightAnchor, constant: -100)
    searchController?.searchBar.delegate = self
    UIBarButtonItem.appearance(whenContainedInInstancesOf: [UISearchBar.self]).setTitleTextAttributes([NSAttributedString.Key(rawValue: NSAttributedString.Key.foregroundColor.rawValue): UIColor.white], for: .normal)

    //Everything with this tap recognizer is an attempt to ensure that the cancel button on the searchbar doesn't disappear.
    let singleTapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(self.cancelSearchBar(sender:)))
    singleTapGestureRecognizer.delegate = self
    singleTapGestureRecognizer.numberOfTapsRequired = 1
    singleTapGestureRecognizer.isEnabled = true
    singleTapGestureRecognizer.cancelsTouchesInView = false
    searchController?.searchBar.addGestureRecognizer(singleTapGestureRecognizer)

    subView.addSubview((searchController?.searchBar)!)
    view.insertSubview(subView, at: 1)

    // When UISearchController presents the results view, present it in
    // this view controller, not one further up the chain.
    definesPresentationContext = true
    searchController?.isActive = true
    searchController?.searchBar.becomeFirstResponder()
    //searchController?.becomeFirstResponder() doesn't work either


}

// this code brings back the cancel button if the user taps in the searchbar's text field. It's an imperfect solution. I'd rather have it so that the searchbar doesn't disappear at all. Not sure how to make that happen yet.
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
    searchController?.isActive = true
    return true
}

键盘和取消按钮目前仅在用户点击文本字段内部时出现。点击屏幕上的任何其他地方会使它们消失。

对于取消按钮,您可以使用 searchBar.showsCancelButton = true 使其自动出现。但是,在键盘出现之前,这不会响应触摸。

在searchBar 上调用.becomeFirstResponder 只会在searchController 完成加载后起作用。请参考以下文章:.

在 viewDidAppear() 中调用 searchBar.becomeFirstResponder(),甚至使用 DispatchQueue.main.async{} 将其强制到主线程(如某些人所建议的那样)都不起作用。从 viewDidLoad() 调用的以下代码片段是我当前的工作解决方案:

    DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(700), execute: {
        self.searchController?.searchBar.becomeFirstResponder()
    })

我可能会调整延迟使其更长,以确保它适用于所有设备。这适用于 iPhoneXR。