【问题标题】:Causing cancel button and software keyboard to appear automatically in viewDidLoad()导致取消按钮和软键盘自动出现在 viewDidLoad()
【发布时间】:2019-11-01 08:13:28
【问题描述】:

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

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

我已经知道如何使用 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
}

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

【问题讨论】:

  • 仅供参考 - 既然您知道 resignFirstResponder,那么您可以看到它是 UIResponder 的一个方法。现在查看UIResponder 的文档并注意与resignFirstResponder 类似的其他方法。
  • 你的意思是 .becomeFirstResponder(),因为我也试过了(忘了把它放进去。抱歉)。如果我的问题确实是重复的,您能否指出我原来的问题,因为正如我所提到的,我没有看到它。
  • 是的,becomeFirstResponder。如果您尝试过,请展示您的尝试。副本的链接位于问题的顶部。
  • 我进行了编辑,表明我尝试了 searchController?.searchBar.becomeFirstResponder() 和 searchController?.becomeFirstResponder()。感谢您指出这一点。

标签: ios swift keyboard cancel-button


【解决方案1】:

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

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

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-06-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-13
    • 2011-04-25
    • 1970-01-01
    • 2021-04-05
    相关资源
    最近更新 更多