我创建了一个带有UITableView
自定义单元格和xib
的视图控制器。在自定义单元格xib中添加了UITextField
。现在我已将UITexField
的代理连接到File的自定义单元格xib的所有者,并在View控制器中添加了以下代码:
extension MyViewController: UITextFieldDelegate {
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
textField.endEditing(true)
return true
}
}
上面的方法没有被调用。
如果我在cellForRowAtindexPath
中添加以下代码,则可以使用
cell.myTextField.delegate = self
有人可以帮助我,为什么将UITextField
代理人连接到自定义单元格中的文件所有者无法正常工作。
修改
我正在注册这样的笔尖:
myTableView.register(UINib(nibName: "MyCustomTableViewCell", bundle: nil), forCellReuseIdentifier: "mycustomcellreuseidentifier")
和cellForRowAtindexPath
:
let cell = tableView.dequeueReusableCell(withIdentifier: "mycustomcellreuseidentifier", for: indexPath) as! MyCustomTableViewCell
除了MyCustomTableViewCell
的{{1}}之外,我还没有在@IBOutlet
中添加任何代码。
编辑 - 在@Puneet Sharma和@Francesco Deliro的帮助下
尝试下面的代码:
UITextField
并且@Puneet Sharma建议在nib内更改File的所有者。通过将类名添加到let myCustomCellNib = UINib(nibName: "MyCustomTableViewCell", bundle: nil)
myCustomCellNib.instantiate(withOwner: self, options: nil)
myTableView.register(myCustomCellNib, forCellReuseIdentifier: "mycustomcellreuseidentifier")
:
仍然无法正常工作。
我应该选择:
MyViewController
cell.myTextField.delegate = self
中的。
答案 0 :(得分:1)
您从未将笔尖的所有者设置为MyViewController。
您必须在提供registerNib:forCellReuseIdentifier:
对象的MyViewController
课程中致电UINib
。
您必须通过调用UINib
创建此init(nibName:bundle:)
个对象。在那里,您尚未将此笔尖的所有者提供为MyViewController
。
关于FileOwner,这是Apple的文档:
文件的所有者对象是一个占位符对象,在此时不会创建 nib文件已加载。而是在代码中创建此对象 并将其传递给nib加载代码。
对于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的Identity inspector选项卡中完成。只需将MyViewController设置为FileOwner即可。
虽然这很有效,但我想如果你需要在cellForRowAtIndexPath:
中写这么多,那么你可以更好地设置代理,就像你在评论代码中所做的那样。
答案 1 :(得分:0)
在@IBOutlet weak var tableView: UITableView!
override func viewDidLoad()
{
super.viewDidLoad()
self.tableView.layer.cornerRadius = 10.0
}
中,自我是cell.myTextField.delegate = self
,与代理人UIViewController
相关联。
如果您已在单元格xib中建立了连接,则您的引用就是单元格。因此,如果您希望连接在那里工作,则必须设置与单元格MyViewController: UITextFieldDelegate
的连接。
修改强> 如果您想在ViewController中使用您的委托,您必须以这种方式关注Puneet答案:
MyCell: UITextFieldDelegate