是否可以更改 TableView 和 SearchBar 委托的处理顺序?
Is it possible to change handling order of TableView and SearchBar Delegates?
我有自定义 class,继承自 UISearchBar
,带有下拉 table 视图,并且两个委托都与此 class 相关。
我注意到,UISearchBarDelegate
方法在 UITableViewDelegate
之前调用,但为了我的目标,我需要更改它。无论如何都可以管理或合并它们吗?
例如,如果用户在 searchField 之外点击,将触发 didEndEditing
方法,键盘将隐藏,所以我也想隐藏我的 tableView
(它提供搜索建议),但有一种情况:当点击 tableView
行时,它也会在 didSelectRow
之前触发 didEndEditing
,而后者将永远不会被调用,因为 tableView
是隐藏,实际上没有单元格。
如果我要从 didEndEditing 中删除关闭 table 视图,当用户点击其他地方时我无法关闭它。
因此,如果可以先处理 tableView
方法,这将对我有很大帮助。也许,可以使用它们的一些通用协议..
private func closeTableView() {
var frame = self.tableView.frame
frame.size.height = 0
self.tableView.frame = frame
self.tableView.sizeToFit()
}
...
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
print("didSelectRowAt")
...
self.closeTableView()
}
extension CustomSearchBar: UISearchBarDelegate {
...
func searchBarTextDidEndEditing(_ searchBar: UISearchBar) {
print("searchBarTextDidEndEditing")
self.setShowsCancelButton(false, animated: true)
self.closeTableView()
}
}
当点击 table 行时,在控制台中只有:
searchBarTextDidEndEditing
您不能更改委托调用的顺序。但是您可以稍等片刻,然后再实际关闭 table 视图:
private var closeTableViewNeeded = false
private func setNeedsCloseTableView() {
guard !closeTableViewNeeded else { return }
closeTableViewNeeded = true
DispatchQueue.main.async { [self] in
closeTableViewNeeded = false
closeTableView()
}
}
并调用 setNeedsCloseTableView()
而不是 closeTableView
通常用 DispatchQueue.main.async
等待下一个 runloop 周期就足够了。由于键盘和 table 视图布局,我不确定这里是否会出现这种情况,因此如果这不起作用,请添加 DispatchQueue.main.asyncAfter(deadline: .now() + 0.1)
而不是 DispatchQueue.main.async
我有自定义 class,继承自 UISearchBar
,带有下拉 table 视图,并且两个委托都与此 class 相关。
我注意到,UISearchBarDelegate
方法在 UITableViewDelegate
之前调用,但为了我的目标,我需要更改它。无论如何都可以管理或合并它们吗?
例如,如果用户在 searchField 之外点击,将触发 didEndEditing
方法,键盘将隐藏,所以我也想隐藏我的 tableView
(它提供搜索建议),但有一种情况:当点击 tableView
行时,它也会在 didSelectRow
之前触发 didEndEditing
,而后者将永远不会被调用,因为 tableView
是隐藏,实际上没有单元格。
如果我要从 didEndEditing 中删除关闭 table 视图,当用户点击其他地方时我无法关闭它。
因此,如果可以先处理 tableView
方法,这将对我有很大帮助。也许,可以使用它们的一些通用协议..
private func closeTableView() {
var frame = self.tableView.frame
frame.size.height = 0
self.tableView.frame = frame
self.tableView.sizeToFit()
}
...
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
print("didSelectRowAt")
...
self.closeTableView()
}
extension CustomSearchBar: UISearchBarDelegate {
...
func searchBarTextDidEndEditing(_ searchBar: UISearchBar) {
print("searchBarTextDidEndEditing")
self.setShowsCancelButton(false, animated: true)
self.closeTableView()
}
}
当点击 table 行时,在控制台中只有:
searchBarTextDidEndEditing
您不能更改委托调用的顺序。但是您可以稍等片刻,然后再实际关闭 table 视图:
private var closeTableViewNeeded = false
private func setNeedsCloseTableView() {
guard !closeTableViewNeeded else { return }
closeTableViewNeeded = true
DispatchQueue.main.async { [self] in
closeTableViewNeeded = false
closeTableView()
}
}
并调用 setNeedsCloseTableView()
而不是 closeTableView
通常用 DispatchQueue.main.async
等待下一个 runloop 周期就足够了。由于键盘和 table 视图布局,我不确定这里是否会出现这种情况,因此如果这不起作用,请添加 DispatchQueue.main.asyncAfter(deadline: .now() + 0.1)
而不是 DispatchQueue.main.async