为什么必须在主队列上异步调用resignFirstResponder()以关闭键盘

问题描述 投票:1回答:3

我使用UISearchBar来过滤表视图的数据,并且我希望在搜索栏没有查询文本时关闭键盘(通过点按键盘上的删除按钮或点按搜索栏上的清除按钮来删除文本)。根据我从stackoverflow上其他文章中学到的信息,我知道即使您在textDidChange UISearchBarDelegate方法中调用searchBar.resignFirstResponder(),单击搜索栏清除按钮(带有x图标的灰色圆形按钮)也将显示键盘。因此,如果单击搜索栏清除按钮,键盘将被隐藏,然后再次闪回,而手动删除文本将隐藏键盘。

唯一的解决方案是在DispatchQueue.main.async代码块内调用resignFirstResponder()方法。

有人可以解释为什么您必须在主队列上异步调用resignFirstResponder()方法来关闭键盘吗?为什么直接调用它不起作用?

检查下面的代码:

    func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
        if searchBar.text?.count == 0 {
            loadItems()

            //the following code works!
            DispatchQueue.main.async {
                searchBar.resignFirstResponder()
            }

//            //this line of code only works when you tap the deleting keyboard button to remove the query text
//            //does not work if you click the searchbar clear button
//            searchBar.resignFirstResponder()
        }
    }
ios swift grand-central-dispatch resignfirstresponder
3个回答
0
投票
简而言之,这是因为您必须等到与您交谈之后才能让搜索栏急救人员辞职。因此,您必须等待textDidChange委托方法退出。这就是异步重新进入主线程所做的事情。

0
投票
[如果您只是好奇为什么会这样,@ matt是正确的。除了他的答案,已经有一个UISearchBarDelegate方法,当您按“取消”按钮时会触发该方法。因此,您可以使用此方法辞退第一响应者。

-1
投票
您可以在文本字段委托方法的endEditing方法中辞职响应者。绝对可以帮助您解决此问题,但是主要的UI更改可能不会在视图中执行。因此,为了更新UI,我们需要在调度主队列中实现。
© www.soinside.com 2019 - 2024. All rights reserved.