将UITextField委托连接到File的自定义表视图单元的所有者不能正常工作Swift 3

时间:2017-10-23 12:15:56

标签: ios swift uitableview uitextfield

我创建了一个带有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")

,我在身份检查器中进行了以下更改

enter image description here

仍然无法正常工作。

我应该选择:

MyViewController
cell.myTextField.delegate = self 中的

2 个答案:

答案 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