UISearchBar:如何防止取消按钮清除文本?

8

我在我的应用中有一个带有UISearchBar的屏幕。当用户进入该屏幕时,搜索栏中可能已经有文本。如果用户然后点击字段并点击取消,则不应清除搜索栏的内容。

这可行吗? 我尝试实现searchBarCancelButtonClicked,但我的对文本属性的修改被忽略了,文本字段仍然被清除了。


你是否正确设置了委托? - Guilherme
不使用“取消”按钮,使用UISearchBar - Akhilrajtr
@Guilherme:是的,我看到了一个测试日志语句被打印出来。 - mavilein
@Akhilrajtr:那么用户应该如何取消操作(使搜索栏失焦)? - mavilein
@mavilein 尝试将自定义选择器设置为“取消”按钮。 - Akhilrajtr
我如何为“取消”按钮分配自定义选择器?似乎不明显如何获取对该按钮的引用。 - mavilein
2个回答

10

我曾遇到同样的问题,解决方法是手动跟踪取消按钮是否被按下的状态。如果是的话,在搜索栏结束编辑时重置文本,因为在searchBarCancelButtonClicked中修改searchBar.text不起作用:

这是我在我的UISearchBarDelegate类中所做的:

var searchTerms = ""
var searchWasCancelled = false

func searchBarTextDidBeginEditing(searchBar: UISearchBar) {
    searchWasCancelled = false
}

func searchBarCancelButtonClicked(searchBar: UISearchBar) {
    searchWasCancelled = true
}

func searchBarTextDidEndEditing(searchBar: UISearchBar) {
    if searchWasCancelled {
        searchBar.text = self.searchTerms
    } else {
        searchTerms = searchBar.text
    }
}

我这里有一个奇怪的行为。它几乎可以正常工作,但如果我输入一些内容,然后按搜索按钮,然后取消它,searchBarTextDidEndEditing委托方法就不会被调用,而searchBar会被清除。 - palme
@palme使用带有下划线的方法:func searchBarTextDidEndEditing(_ searchBar: UISearchBar) - Robert Dresler
"searchBarTextDidEndEditing代理方法从未被调用。" - palme

0

关于此事,有些更新。在 iOS 15 中,似乎会改变 searchBarCancelButtonClickedsearchBarTextDidEndEditing 代理方法的调用顺序。

在 iOS 15 之前,以下类似于状态的解决方案对于大多数用例都是适用的:


var searchTerms = ""
var searchWasCancelled = false

func searchBarTextDidBeginEditing(searchBar: UISearchBar) {
    searchWasCancelled = false
}

func searchBarCancelButtonClicked(searchBar: UISearchBar) {
    searchWasCancelled = true
}

func searchBarTextDidEndEditing(searchBar: UISearchBar) {
    if searchWasCancelled {
        searchBar.text = self.searchTerms
    } else {
        searchTerms = searchBar.text
    }
}

遗憾的是,在iOS 15中,这个问题出现了。经过一番快速调查,我发现在searchBarCancelButtonClicked方法之前,searchBarTextDidEndEditing委托方法总是被调用。目前还不清楚这是否是苹果有意更改的结果,或者确实是一个错误。

除此之外,我找到了一个简单的解决方法来回答原始问题,并发现从异步调度块设置searchBar.text将成功修改文本。像这样:

var previousSearchTerm = ""

func searchBarTextDidBeginEditing(searchBar: UISearchBar) {
    previousSearchTerm = searchBar.text ?? ""
}

func searchBarCancelButtonClicked(searchBar: UISearchBar) {
    DispatchQueue.main.async {
        searchBar.text = self.previousSearchTerm
    }
}

现在这个方法适用于iOS 15及之前的版本,在我的特定使用情况下是有效的。然而,根据你想要实现的目标,这可能不足以保证向后兼容性。值得注意的是,像任何其他修改UIKit顽固默认行为的解决方法一样,这种方法存在未知副作用的风险,无论是现在还是将来。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接