如何将UITextFieldDelegate迁移至ViewModel?Delegate赋值报错求助
问题根源
你自定义的TextFieldDelegate协议和系统原生的UITextFieldDelegate是两个完全独立的协议,你的ViewModel仅遵循了自定义协议,并不符合系统文本框代理的类型要求,因此直接赋值会报错,强行类型转换也会返回nil,导致代理方法无法触发。
解决方案
以下三种方式都可以解决问题,根据你的实际需求选择:
方式一:让自定义协议继承系统协议
修改自定义协议的定义,让它直接继承UITextFieldDelegate,这样ViewModel遵循自定义协议后,会自动符合系统代理的类型要求:
// 修改自定义协议,继承系统的UITextFieldDelegate protocol TextFieldDelegate: UITextFieldDelegate { // 可添加自定义方法,也可仅复用系统协议方法 } extension ViewModel: TextFieldDelegate { func textFieldShouldReturn(_ textField: UITextField) -> Bool { search() textField.resignFirstResponder() return true } }
之后直接赋值即可,无需类型转换:
searchView.textField.delegate = viewModel
方式二:直接让ViewModel遵循系统协议
如果你的自定义协议仅用于实现textFieldShouldReturn方法,完全可以去掉自定义协议,直接让ViewModel遵循系统原生的UITextFieldDelegate:
extension ViewModel: UITextFieldDelegate { func textFieldShouldReturn(_ textField: UITextField) -> Bool { search() textField.resignFirstResponder() return true } }
同样直接赋值即可:
searchView.textField.delegate = viewModel
方式三:让ViewModel同时遵循两个协议
如果必须保留自定义协议,可让ViewModel同时遵循自定义协议和系统协议(由于方法签名一致,无需重复实现):
protocol TextFieldDelegate: AnyObject { func textFieldShouldReturn(_ textField: UITextField) -> Bool } extension ViewModel: TextFieldDelegate, UITextFieldDelegate { func textFieldShouldReturn(_ textField: UITextField) -> Bool { search() textField.resignFirstResponder() return true } }
之后直接赋值系统代理即可,类型匹配不会报错。
内容的提问来源于stack exchange,提问作者HBK
相关产品推荐
相关产品推荐

