ios swift类一致性协议
我正在努力学习swift,并希望使用面向协议的编程方法。我想要实现的很简单,但我找不到任何方法 假设我有一个出口,它是textfield。我希望textfield符合类似ValidateName协议的协议。有什么办法吗? 我不想创建一个新类,它是UITextField的子类,并且符合协议。我想用这个特殊的属性ios swift类一致性协议,ios,swift,protocols,protocol-oriented,Ios,Swift,Protocols,Protocol Oriented,我正在努力学习swift,并希望使用面向协议的编程方法。我想要实现的很简单,但我找不到任何方法 假设我有一个出口,它是textfield。我希望textfield符合类似ValidateName协议的协议。有什么办法吗? 我不想创建一个新类,它是UITextField的子类,并且符合协议。我想用这个特殊的属性 @IBOutlet weak var nameTextField:UITextField!<Conforms ValidatesName> @IBOutlet weak var
@IBOutlet weak var nameTextField:UITextField!<Conforms ValidatesName>
@IBOutlet weak var emailTextField:UITextField!<Conforms ValidatesEmail>
@IBOutlet weak var passwordTextField:UITextField!<Conforms ValidatesPassword>
@ibextfield:UITextField!
@IBOutlet弱var emailTextField:UITextField!
@IBOutlet弱var密码文本字段:UITextField!
谢谢不幸的是,有一些限制阻止了这一点:
不幸的是,有一些限制阻止了这一点:
您的问题是,虽然可以通过扩展添加协议一致性,但扩展应用于类,而不是该类的实例。这意味着你可以这样说:
extension UITextField: ValidatesName {...}
@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的所有实例符合ValidatesName
同样,你也可以说
extension UITextField: ValidatesEmail{...}
但是现在UITextField的所有实例都将符合validateName
和validateMail
使用单独的验证…
协议似乎不是正确的方法。协议的基本签名类似于var isValid:Bool
;这不会在姓名和电子邮件之间更改。改变的是验证逻辑,它必须存在于某个地方。这一点,再加上您需要子类才能使用Interface Builder这一事实,表明可以由各种子类采用的单个协议Validatable
是一种更合理的方法
protocol Validatable {
var isValid: Bool { get }
}
现在,您可以定义符合此协议的UITextField子类(如果愿意,您可以通过子类的扩展添加一致性,我只是想在这里节省空间)
现在,您可以将文本字段添加到数组中,并具有如下内容:
extension UITextField: ValidatesName {...}
@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")
}
}
您的问题是,虽然可以通过扩展添加协议一致性,但扩展应用于类,而不是该类的实例。这意味着你可以这样说:
extension UITextField: ValidatesName {...}
@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的所有实例符合ValidatesName
同样,你也可以说
extension UITextField: ValidatesEmail{...}
但是现在UITextField的所有实例都将符合validateName
和validateMail
使用单独的验证…
协议似乎不是正确的方法。协议的基本签名类似于var isValid:Bool
;这不会在姓名和电子邮件之间更改。改变的是验证逻辑,它必须存在于某个地方。这一点,再加上您需要子类才能使用Interface Builder这一事实,表明可以由各种子类采用的单个协议Validatable
是一种更合理的方法
protocol Validatable {
var isValid: Bool { get }
}
现在,您可以定义符合此协议的UITextField子类(如果愿意,您可以通过子类的扩展添加一致性,我只是想在这里节省空间)
现在,您可以将文本字段添加到数组中,并具有如下内容:
extension UITextField: ValidatesName {...}
@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类不符合您想要的协议,协议的采用是基于协议中定义的方法和属性的实现。如果我理解正确,我已经可以定义这样的方法了。我想我可以为变量做这件事。>但是问题是UITextField类不符合您想要的协议,协议的采用是基于协议中定义的方法和属性的实现。如果我理解正确,我已经可以定义这样的方法了。我想我可以为变量做这件事。>如何将IBOutletCollection数组类型编写为唯一的协议,我尝试过,但遇到了错误。如果尝试将其实现为[ProtocolName],则会出现错误。您是对的,抱歉。我更新了我的答案。您需要自己构建阵列。这是Objective-C的传统限制了您在Swift中所能做的事情的地方之一。这是一个很好的答案,可以将它们用作阵列,以防止viewcontroller中出现大量警卫。我唯一要更改的是nameTextField和emailTextField是视图。它们不是presenter(MVP),也不是view model(MVVM),因此我将对其进行一些更改,但要感谢validatableFields的想法。我如何才能将IBMoutletCollection数组类型编写为唯一的协议,我尝试了,但出现了错误。如果尝试将其实现为[ProtocolName],则会出现错误。您是对的,抱歉。