是否可以更改 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