UITextField 无法成为 UITableView 中的第一响应者
UITextField can't become first responder in UITableView
上下文
基本清单。当用户按下“+”时,代码会创建一个新项目,其中包含用户可以更改的默认文本。
问题
我想在用户按下“+”时立即聚焦新项目,以便用户可以键入所需的名称。我尝试使用以下代码实现此目的:
func focus() {
title.becomeFirstResponder()
title.selectAll(nil)
}
但是becomeFirstResponder()
总是returnsfalse
.
如何在创建后 UITableviewCell
中将焦点放在 UITextField
上?
这里是UITableViewController
的完整代码供参考:
import UIKit
class ViewController: UITableViewController{
var model: [String] = ["Existing item"]
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return model.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "ItemUI", for: indexPath) as! ItemUI
cell.update(with: model[indexPath.item])
return cell
}
@IBAction func createItem(_ sender: UIBarButtonItem) {
let indexPath = IndexPath(item: model.count, section: 0)
model.append("new item")
tableView.reloadData()
tableView.scrollToRow(at: indexPath, at: .top, animated: true)
DispatchQueue.main.asyncAfter(deadline: .now() + 0.25) {
let cell = self.tableView(self.tableView, cellForRowAt: indexPath) as! ItemUI
cell.focus()
}
}
}
class ItemUI: UITableViewCell{
@IBOutlet var title: UITextField!
func update(with: String) {
title.text = with
}
func focus() {
title.becomeFirstResponder()
title.selectAll(nil)
}
}
您可以在您的视图控制器中添加一个布尔值来跟踪添加项,即 isAddingItem,默认值为 false,当您添加新项时,只需更新 isAddingItem 为真。在 tableview cellForRowAt 方法中检查 tableview 的最后一个单元格,如果 isAddingItem 为真,则选择文本字段的所有文本并使其成为第一响应者。
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "ItemUI", for: indexPath) as! ItemUI
cell.update(with: model[indexPath.item])
if isAddingItem && indexPath.item == model.count {
// make your textfield first here and select text here
}
return cell
}
同时检查您是否设置了文本字段委托。
好的,我找到问题了!
我使用方法 self.tableView(self.tableView, cellForRowAt: indexPath)
而不是 self.tableView.cellForRow(at: indexPath)
。
以下是 documentation 所说的内容:
“永远不要自己调用此方法。如果您想从 table 中检索单元格,请改为调用 table 视图的 cellForRow(at:)
方法。”
上下文
基本清单。当用户按下“+”时,代码会创建一个新项目,其中包含用户可以更改的默认文本。
问题
我想在用户按下“+”时立即聚焦新项目,以便用户可以键入所需的名称。我尝试使用以下代码实现此目的:
func focus() {
title.becomeFirstResponder()
title.selectAll(nil)
}
但是becomeFirstResponder()
总是returnsfalse
.
如何在创建后 UITableviewCell
中将焦点放在 UITextField
上?
这里是UITableViewController
的完整代码供参考:
import UIKit
class ViewController: UITableViewController{
var model: [String] = ["Existing item"]
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return model.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "ItemUI", for: indexPath) as! ItemUI
cell.update(with: model[indexPath.item])
return cell
}
@IBAction func createItem(_ sender: UIBarButtonItem) {
let indexPath = IndexPath(item: model.count, section: 0)
model.append("new item")
tableView.reloadData()
tableView.scrollToRow(at: indexPath, at: .top, animated: true)
DispatchQueue.main.asyncAfter(deadline: .now() + 0.25) {
let cell = self.tableView(self.tableView, cellForRowAt: indexPath) as! ItemUI
cell.focus()
}
}
}
class ItemUI: UITableViewCell{
@IBOutlet var title: UITextField!
func update(with: String) {
title.text = with
}
func focus() {
title.becomeFirstResponder()
title.selectAll(nil)
}
}
您可以在您的视图控制器中添加一个布尔值来跟踪添加项,即 isAddingItem,默认值为 false,当您添加新项时,只需更新 isAddingItem 为真。在 tableview cellForRowAt 方法中检查 tableview 的最后一个单元格,如果 isAddingItem 为真,则选择文本字段的所有文本并使其成为第一响应者。
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "ItemUI", for: indexPath) as! ItemUI
cell.update(with: model[indexPath.item])
if isAddingItem && indexPath.item == model.count {
// make your textfield first here and select text here
}
return cell
}
同时检查您是否设置了文本字段委托。
好的,我找到问题了!
我使用方法 self.tableView(self.tableView, cellForRowAt: indexPath)
而不是 self.tableView.cellForRow(at: indexPath)
。
以下是 documentation 所说的内容:
“永远不要自己调用此方法。如果您想从 table 中检索单元格,请改为调用 table 视图的 cellForRow(at:)
方法。”