Swift中子ViewController的UITextFieldDelegate无法触发求助
问题分析与解决办法
你遇到的问题核心在于每次调用SecondViewController()都会创建一个全新的实例,而你在按钮点击事件里先后创建了三个完全独立的SecondViewController对象,导致设置了代理的那个实例根本没有被显示在界面上,自然shouldChangeCharactersIn方法不会被触发。
错误代码的问题所在
看你这段按钮点击代码:
@IBAction func btnPressed(_ sender: Any) { addChildViewController(SecondViewController()) view.superview?.addSubview(SecondViewController().view) SecondViewController().view.frame = (view.superview?.bounds)! SecondViewController().view.autoresizingMask = [.flexibleWidth, .flexibleHeight] SecondViewController().didMove(toParentViewController: self) }
这里每一行的SecondViewController()都是一个新的对象:
- 第一个被添加为子控制器,但没有被关联到任何视图
- 第二个的视图被添加到父视图,但这个vc实例没有被添加为子控制器
- 后面两行操作的又是另外两个全新的vc实例的视图
最后这些实例之间完全没有关联,显示在界面上的那个vc实例,你根本没给它的textField设置代理(甚至可能你在xib或代码里设置代理的是另一个未被显示的实例)。
修正后的代码
你需要先创建一个SecondViewController的实例,然后对同一个实例进行所有操作:
@IBAction func btnPressed(_ sender: Any) { // 只创建一次实例,后续所有操作都用这个实例 let secondVC = SecondViewController() // 添加为子控制器 addChild(secondVC) // 添加视图到父视图 if let superView = view.superview { secondVC.view.frame = superView.bounds secondVC.view.autoresizingMask = [.flexibleWidth, .flexibleHeight] superView.addSubview(secondVC.view) } // 完成子控制器的添加流程 secondVC.didMove(toParent: self) }
另外,注意从iOS 11开始,addChildViewController(_:)已经被废弃,推荐使用addChild(_:),didMove(toParentViewController:)对应didMove(toParent:)。
额外检查点
确保你在SecondViewController里正确设置了textField的代理:
- 如果用代码设置,要确保是在同一个实例里,比如在
viewDidLoad中:
override func viewDidLoad() { super.viewDidLoad() myTextField.delegate = self }
- 如果用xib设置,要确保xib关联的是当前
SecondViewController实例的textField,并且代理连线正确(不要误连到其他对象)。
这样修改后,显示在界面上的SecondViewController实例就是你设置了代理的那个,shouldChangeCharactersIn方法应该就能正常触发了。
内容的提问来源于stack exchange,提问作者ZephyrYK
相关产品推荐
相关产品推荐

