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
You can't change order of delegate calls. But you can wait a little bit before actually closing your table view:
And call
setNeedsCloseTableView()instead ofcloseTableViewUsually waiting next runloop cycle with
DispatchQueue.main.asyncis 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 addDispatchQueue.main.asyncAfter(deadline: .now() + 0.1)instead ofDispatchQueue.main.async