Home > OS >  Is it possible to change handling order of TableView and SearchBar Delegates?
Is it possible to change handling order of TableView and SearchBar Delegates?

Time:09-17

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

  • Related