【问题标题】:TableView viewForHeaderInSection Won't Resume First ResponderTableView viewForHeaderInSection 不会恢复第一响应者
【发布时间】: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 中令人困惑,但我第一次点击它时,它是第一响应者,然后又不是。有谁知道我怎样才能让它恢复成为第一响应者?

【问题讨论】:

标签: swift uitableview resignfirstresponder becomefirstresponder


【解决方案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()
          } 
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-05-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-12-31
        • 1970-01-01
        相关资源
        最近更新 更多