TableView viewForHeaderInSection 不会恢复 First Responder

TableView viewForHeaderInSection Won't Resume First Responder

这里的情况很奇怪,希望有人能帮忙。基本上,我有一个这样的开关:

private var searchMode = false {
    didSet {
        if !searchMode {
            self.tableView.endEditing(true)
        }
        tableView.reloadData()
    }
}

当我按下按钮时它会切换:

@objc func searchTapped() {
    searchMode.toggle()
}

我的header是这样设置的:

func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
    if searchMode {
        let header = tableView.dequeueReusableHeaderFooterView(withIdentifier: "searchHeader") as! SearchTableViewHeader
        header.searchField.becomeFirstResponder()
        header.searchField.addTarget(self, action: #selector(textFieldDidChange(textField:)), for: .editingChanged)
        return header
    } else {
        let header = tableView.dequeueReusableHeaderFooterView(withIdentifier: "blueHeader") as! OpaqueBlueTableViewHeader
        header.titleLabel.text = "Discover Innovative Services"
        header.subtitleLabel.text = "Learn about our comprehensive range of services"
        return header
    }
}

到目前为止一切顺利。事情是这样的。我第一次单击按钮时,searchMode 变为 true,我的 UITextfield 出现,而​​且它是正确的第一响应者。到目前为止,一切都很好。然后,当我再次单击它时,文本字段消失了。到目前为止,一切都很好。但是,当我再次单击它时,textField 正确显示,但响应者的时间太长了!让我告诉你问题所在。

gif看得一头雾水,但是第一次点击是第一响应者,之后就不是了。有谁知道我怎样才能让它恢复为第一响应者?

尝试:

func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {


if searchMode {



} else {
    let previousHeader = tableView.dequeueReusableHeaderFooterView(withIdentifier: "searchHeader") as! SearchTableViewHeader
  previousHeader.searchField.resignFirstResponder()

   }
 }

您可以尝试以下两种方法:

  • reloadData() 调用之后调用 tableView.layoutIfNeeded() 并使 header 之后查看第一响应者:
if !searchMode {
    self.tableView.endEditing(true)
}
tableView.reloadData()
tableView.layoutIfNeeded()
if let headerView = tableView.headerView(forSection: 0) as? SearchTableViewHeader {
    header.searchField.becomeFirstResponder()
}
  • 按照建议实施 tableView.reloadDataWithCompletion here 并在完成块中调用 makeFirstResponder:
if !searchMode {
    self.tableView.endEditing(true)
}
tableView.reloadData() {
    if let headerView = tableView.headerView(forSection: 0) as? SearchTableViewHeader {
        header.searchField.becomeFirstResponder()
    } 
}

好的,这些方法很有用,但我发现这是唯一有效的答案:

首先,在textField消失后调用reloadData()

之前退出第一响应者
 private var searchMode = false {
        didSet {
            if let tv = self.tableView.headerView(forSection: 0), let stv = tv as? SearchTableViewHeader {
                stv.searchField.resignFirstResponder()
            }
            tableView.reloadData()
        }
    }

然后,在最后一个tableView函数中设置first responder。 这是因为在 viewForHeader

中设置第一响应者时出现意外行为
func tableView(_ tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int) {
    if searchMode, let stv = view as? SearchTableViewHeader {
        stv.searchField.becomeFirstResponder()
    }
}