我创建了一个具有 UITableView
的 View Controller ,其中包含自定义单元格和 xib
。在自定义单元 xib 中添加了 UITextField
。现在我已将 UITexField
的委托(delegate)连接到自定义单元 xib 的文件所有者,并在 View Controller 中添加了以下代码:
extension MyViewController: UITextFieldDelegate {
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
textField.endEditing(true)
return true
}
}
上面的方法没有被调用。
如果我在 cellForRowAtindexPath
中添加以下代码,它就可以工作:
cell.myTextField.delegate = self
有人可以帮助我,为什么将 UITextField
委托(delegate)连接到自定义单元格中的文件所有者不起作用。
编辑
我正在像这样注册 Nib :
myTableView.register(UINib(nibName: "MyCustomTableViewCell", bundle: nil), forCellReuseIdentifier: "mycustomcellreuseidentifier")
在cellForRowAtindexPath
中:
let cell = tableView.dequeueReusableCell(withIdentifier: "mycustomcellreuseidentifier", for: indexPath) as! MyCustomTableViewCell
除了 UITextField
的 @IBOutlet
之外,我没有在 MyCustomTableViewCell
中添加任何代码。
编辑 - 在 @Puneet Sharma 和 @Francesco Deliro 的帮助下
尝试了以下代码:
let myCustomCellNib = UINib(nibName: "MyCustomTableViewCell", bundle: nil)
myCustomCellNib.instantiate(withOwner: self, options: nil)
myTableView.register(myCustomCellNib, forCellReuseIdentifier: "mycustomcellreuseidentifier")
正如@Puneet Sharma 建议更改 Nib 内的文件所有者。我通过将类名添加到 MyViewController 中,在身份检查器中进行了以下更改:
仍然无法工作。
我应该选择:
cell.myTextField.delegate = self
在cellForRowAtindexPath
中。
最佳答案
您从未将 Nib 的所有者设置为 MyViewController。
您必须在 MyViewController
类中调用 registerNib:forCellReuseIdentifier:
,并在其中提供 UINib
对象。
您必须通过调用 init(nibName:bundle:)
创建了此 UINib
对象。在那里,您尚未将此 Nib 的所有者提供为 MyViewController
。
关于FileOwner ,这是来自 Apple 的文档:
File’s Owner object is a placeholder object that is not created when the nib file is loaded. Instead, you create this object in your code and pass it to the nib-loading code.
对于 UIViewController nib/storyboard,FileOwner 已由 XCode 模板设置,因此您可以直接进行 IBOutlet 连接。
如果是自定义 tableviewCell,则需要通过代码提供文件所有者。
这可以使用 nib 对象上的 [instantiate(withOwner:options:)][2] 方法来完成(我无耻地从上面的 Fransesco 答案中复制了代码)。
let nib = UINib(nibName: "MyCustomTableViewCell", bundle: nil)
nib.instantiate(withOwner: self, options: nil)
myTableView.register(nib, forCellReuseIdentifier: "mycustomcellreuseidentifier")
早些时候,我认为可以使用instantiate(withOwner:)的UINib方法来设置文件所有者。方法,但是虽然该方法用于设置 nib 所有者,但在 tableview.register(nib:)
方法的情况下不起作用。
这可能是因为当 tableview 第一次尝试使单元格出队并且找不到单元格时,它会从注册的 nib 中创建单元格,但将其所有者设置为 nil。我还没有找到支持这一点的官方文档,但这可能是正在发生的情况,导致示例项目出现问题。
我已从示例中删除了 registerNib 代码,并在 cellForRowAtIndexPath: 中创建了单元格,并且这有效。
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
var cell = tableView.dequeueReusableCell(withIdentifier: "mycellreuseidentifier") as? MyTableViewCell
if cell == nil {
let array = Bundle.main.loadNibNamed("MyTableViewCell", owner: self, options: nil)
cell = array!.first as! MyTableViewCell
}
return cell!
}
仅此一点还不够。您必须将 nib 内的文件所有者更改为 MyViewController。这将在 Nib 的“身份检查器”选项卡中完成。只需将 MyViewController 设置为 FileOwner 即可。
虽然,这有效,但我想如果您需要在 cellForRowAtIndexPath:
中写这么多,最好您在那里设置委托(delegate),就像您在注释代码中所做的那样。
关于ios - 将 UITextField 委托(delegate)连接到自定义 TableView 单元格的文件所有者不起作用 Swift 3,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46889140/