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:) 方法。”