导致取消按钮和软件键盘自动显示在viewDidLoad()

时间:2019-06-18 16:15:24

标签: ios swift keyboard cancel-button

注意:如上链接所示,我尝试使用.becomeFirstResponder()。在第一篇文章中,我愚蠢地忽略了这一细节。查看我的代码进行修改。

我在自己专用的viewController中使用UISearchBar(用于搜索栏的代码来自Google,作为其SDK的一部分)。一旦应用程序锁定到该viewController中,我希望键盘在没有用户干预的情况下立即显示,并且我不希望它消失。更重要的是,我希望取消按钮始终保持可见状态。

我已经知道如何使用resignFirstResponder使键盘消失。我尝试使用.becomeFirstResponder()无效。但是,在StackOverflow,Google以及Apple的文档中,我没有看到一种无需用户干预即可使其显示的方法。

所有功能(例如editingDidBegin())都要求用户执行某些操作。

这感觉很基础,但是我空了。

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

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

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

//在viewDidLoad()中调用

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
}

当前,只有当用户在文本字段内点击时,键盘和取消按钮才会出现。在屏幕上的其他任何地方轻按都会使它们消失。

1 个答案:

答案 0 :(得分:0)

对于取消按钮,可以使用searchBar.showsCancelButton = true使其自动显示。但是,只有在键盘出现时,它才能响应触摸。

仅在searchController完成加载后,才在searchBar上调用.becomeFirstResponder。请参考以下文章:Cannot set searchBar as firstResponder

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

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

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