TableView viewForHeaderInSection 不会恢复第一响应者

Posted

技术标签:

【中文标题】TableView viewForHeaderInSection 不会恢复第一响应者【英文标题】:TableView viewForHeaderInSection Won't Resume First Responder 【发布时间】:2020-01-18 05:08:59 【问题描述】:

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

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

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

@objc func searchTapped() 
    searchMode.toggle()

我的标题是这样设置的:

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 中令人困惑,但我第一次点击它时,它是第一响应者,然后又不是。有谁知道我怎样才能让它恢复成为第一响应者?

【问题讨论】:

可能是这个帮助:***.com/questions/30445823/… 我试过这种方法。它让我辞职响应者罚款,但它不会恢复第一响应者.. :( 【参考方案1】:

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

首先,在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 函数中设置第一响应者。 这是因为在 viewForHeader 中设置第一响应者存在意外行为

func tableView(_ tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int) 
    if searchMode, let stv = view as? SearchTableViewHeader 
        stv.searchField.becomeFirstResponder()
    

【讨论】:

【参考方案2】:

试试:

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


if searchMode 



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

   
 

【讨论】:

【参考方案3】:

您可以尝试以下两件事:

reloadData() 调用之后调用tableView.layoutIfNeeded() 并使标题视图成为之后的第一响应者:
if !searchMode 
    self.tableView.endEditing(true)

tableView.reloadData()
tableView.layoutIfNeeded()
if let headerView = tableView.headerView(forSection: 0) as? SearchTableViewHeader 
    header.searchField.becomeFirstResponder()

按照here 的建议实现 tableView.reloadDataWithCompletion 并在完成块中调用 makeFirstResponder:
if !searchMode 
    self.tableView.endEditing(true)

tableView.reloadData() 
    if let headerView = tableView.headerView(forSection: 0) as? SearchTableViewHeader 
        header.searchField.becomeFirstResponder()
     

【讨论】:

以上是关于TableView viewForHeaderInSection 不会恢复第一响应者的主要内容,如果未能解决你的问题,请参考以下文章

tableView(cellForRowAtIndexPath) 与 tableView.cellForRowAtIndexPath()?

TableView里面的tableview cell swift 3

将 tapGesture 添加到 tableView 则无法执行 tableView(_ tableView: UITableView, didSelectRowAt indexPath: Index

Swift:tableView 行的高度,其 tableView 单元格具有动态行数的嵌套 tableView

IOS:两个tableview的tableview委托方法

iOS tableview上textView在编辑状态时,tableview自动上移的功能