如何通过selector设置UITextField调用becomeFirstResponder跳转下一个输入框
UITextField自定义工具栏点击完成按钮无响应问题解决方案
问题根源
你的实现错误根源是UIBarButtonItem的target参数和传入的selector所属对象不匹配:
- 你在
addToolbar扩展方法中,将完成按钮的target固定写死为self,也就是当前调用该方法的UITextField实例。当传入selector为nil时,默认使用的#selector(resignFirstResponder)是UITextField本身自带的方法,因此调用逻辑正常。 - 你传入的
#selector(nextTextField.becomeFirstResponder)对应的方法执行主体是nextTextField实例,按钮触发时系统会尝试在当前UITextField实例上调用该方法,自然不会生效。你之前测试自定义带print的方法不生效也是同样原因:方法属于你的ViewController,但是target是UITextField,Runtime找不到对应方法实现。
解决方案
方案1:修改扩展支持传入target参数
调整扩展代码,增加target参数允许外部传入方法的执行主体:
func addToolbar(target: Any? = nil, selector: Selector? = nil) { let action: Selector let actionTarget: Any? if let selector = selector, let target = target { action = selector actionTarget = target } else { action = #selector(resignFirstResponder) actionTarget = self } let flexibleSpace = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil) let doneButton = UIBarButtonItem(barButtonSystemItem: .done, target: actionTarget, action: action) let toolbar = UIToolbar() toolbar.items = [flexibleSpace, doneButton] toolbar.sizeToFit() toolbar.layoutIfNeeded() inputAccessoryView = toolbar returnKeyType = .done }
调用时直接传入nextTextField作为target即可:
myTextField.addToolbar(target: nextTextField, selector: #selector(nextTextField.becomeFirstResponder))
方案2:绑定控制器自定义方法
如果跳转前需要执行额外逻辑(比如保存当前选中值、校验输入等),可以在当前ViewController中自定义跳转方法,再绑定到按钮:
- 在ViewController中添加@objc修饰的跳转方法:
@objc func handlePickerDone() { // 可在这里添加额外业务逻辑 nextTextField.becomeFirstResponder() }
- 调用扩展时传入当前ViewController作为target:
myTextField.addToolbar(target: self, selector: #selector(handlePickerDone))
内容的提问来源于stack exchange,提问作者kuemme01
相关产品推荐
相关产品推荐

