簡體   English   中英

iOS Swift類符合協議

[英]ios swift class conforming protocol

我正在嘗試快速學習,並希望使用面向協議的編程方法。 我想要實現的目標很簡單,但我找不到任何方法。

可以說我有Outlet就是textfield。 我希望該文本字段符合ValidatesName協議之類的協議。 有什么辦法嗎? 我不想創建子類UITextField並符合協議的新類。 我要用於此特定屬性。

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

謝謝

您的問題是,盡管您可以通過擴展名添加協議一致性,但該擴展名將應用於該類,而不是該類的實例。 這意味着您可以說類似以下內容:

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")
    }
}

不幸的是,有一些限制可以防止這種情況:

  1. IBOutlet必須引用從NSObject繼承的類,可能是為了啟用存檔/解碼,因此您不能僅將協議用於IBOutlet的類型

  2. 在Swift中,沒有辦法將變量的類型聲明為具體類型+協議一致性的組合,就像您在示例中所做的那樣

  3. 在Objective-C中,您可以聲明具體的類型+協議一致性,但是協議仍然會被IBOutlets忽略,這可能是因為協議一致性是在運行時檢查的,並且Xcode / Interface Builder在設計時不一定知道對象最終是否會遵守協議。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM