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()
}
}
这里的情况很奇怪,希望有人能帮忙。基本上,我有一个这样的开关:
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()
}
}