I have custom class, inherited from UISearchBar
with dropdown tableview, and both delegates related to this class.
I've notice, that UISearchBarDelegate
methods calls before UITableViewDelegate
, but for my goals I need to change it. Is it possible anyhow to manage them, or combine?
For example, if user will tap outside of searchField, didEndEditing
method will be triggered, and keyboard will hide, so I want to hide my tableView
too (it presents search suggestion), but there is one case : when tapping to tableView
row, it's triggered didEndEditing
too, before the didSelectRow
, which, in turn, will never be called, because tableView
is hidden, and there is actually no cells.
If I will remove closeing tableview from didEndEditing, I could not close it, when user tap somewhere else.
So if it's possible to handle tableView
methods first, it will help me a lot. Maybe, some generic protocol for them could be used..
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()
}
}
and when tap on the table row, in console is only:
searchBarTextDidEndEditing
CodePudding user response:
You can't change order of delegate calls. But you can wait a little bit before actually closing your table view:
private var closeTableViewNeeded = false
private func setNeedsCloseTableView() {
guard !closeTableViewNeeded else { return }
closeTableViewNeeded = true
DispatchQueue.main.async { [self] in
closeTableViewNeeded = false
closeTableView()
}
}
And call setNeedsCloseTableView()
instead of closeTableView
Usually waiting next runloop cycle with DispatchQueue.main.async
is enough. I'm not sure it that'll be the case here because of keyboard and table view layout, so if this won't work add DispatchQueue.main.asyncAfter(deadline: .now() 0.1)
instead of DispatchQueue.main.async