您的问题是,尽管您可以通过扩展添加协议一致性,但扩展应用于该类,而不是该类的一个实例。这意味着,你可以这样说:
extension UITextField: ValidatesName {...}
但是,这将使的UITextField的所有实例符合ValidatesName
同样,你也可以说
extension UITextField: ValidatesEmail{...}
但现在所有 UITextField的实例将符合ValidatesName
和ValidatesEmail
。
拥有单独的Validates...
协议似乎不是正确的方法。协议的基本签名是类似于var isValid: Bool
;这在姓名和电子邮件之间不会改变。什么是变化是验证逻辑,这必须住在某个地方。这一点,加上你需要使用子类来与Interface Builder一起工作的事实表明,可以由你的各种子类采用的单一协议Validatable
是一种更合理的方法。现在
protocol Validatable {
var isValid: Bool { get }
}
,您可以定义符合本协议的UITextField的子类(你可以,如果你想通过添加扩展的符合你的子类,我只是想在这里保存空间)
class NameTextField: UITextField, Validatable {
var isValid: Bool {
get {
guard let text = self.text else {
return false
}
return !text.isEmpty
}
}
}
class EmailTextField: UITextField, Validatable {
var isValid: Bool {
get {
guard let text = self.text else {
return false
}
return text.contains("@")
}
}
}
现在,您可以添加文本框到一个数组中,并有类似:
@IBOutlet weak var nameTextField:NameTextField!
@IBOutlet weak var emailTextField:EmailTextField!
var validatableFields:[Validatable]!
override func viewDidLoad() {
super.viewDidLoad()
self.validatableFields = [nameTextField,emailTextField]
}
...
for field in validateableFields {
if !field.isValid() {
print("A field isn't valid")
}
}
但问题是,UITextField类不符合你的期望的协议,该协议采用基于实施Ø f在协议中定义的方法和属性 –
如果我理解正确,我已经可以定义一些像这样的方法。我认为我可以为变量做到这一点。> –
kekkeme