You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 23:02:36