gpt4 book ai didi

ios swift类符合协议(protocol)

转载 作者:搜寻专家 更新时间:2023-11-01 06:17:42 24 4
gpt4 key购买 nike

我正在努力学习 Swift 并希望使用面向协议(protocol)的编程方法。我想要实现的目标很简单,但我找不到任何方法。

假设我有 Outlet,它是文本字段。我希望该文本字段符合 ValidatesName 协议(protocol)之类的协议(protocol)。有什么办法吗?我不想创建子类 UITextField 并符合协议(protocol)的新类。我想用于此特定属性。

@IBOutlet weak var nameTextField:UITextField!<Conforms ValidatesName>
@IBOutlet weak var emailTextField:UITextField!<Conforms ValidatesEmail>
@IBOutlet weak var passwordTextField:UITextField!<Conforms ValidatesPassword>

谢谢

最佳答案

您的问题是,虽然您可以通过扩展添加协议(protocol)一致性,但扩展应用于类,而不是该类的实例。这意味着您可以这样说:

extension UITextField: ValidatesName {...}

但这将使 UITextField 的所有实例符合 ValidatesName

同样,你也可以说

extension UITextField: ValidatesEmail{...}

但现在所有 UITextField 实例都将符合ValidatesName ValidatesEmail

拥有单独的 Validates... 协议(protocol)似乎无论如何都不是正确的方法。协议(protocol)的基本签名类似于 var isValid: Bool;这在姓名和电子邮件之间不会改变。真正改变的是验证逻辑,它必须存在于某个地方。这一点,再加上您需要子类才能与 Interface Builder 一起工作的事实,这表明您的各种子类可以采用的单一协议(protocol) Validatable 是一种更合理的方法。

protocol Validatable  {
var isValid: Bool { get }
}

现在,您可以定义符合此协议(protocol)的 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")
}
}

关于ios swift类符合协议(protocol),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40794489/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com