簡體   English   中英

通用函數輸出到UITextField或UILabel

[英]Generic Function to Output to UITextField or UILabel

我正在嘗試在iOS的Swift 2中編寫一個處理一些文本並將其寫入UITextField UILabel的函數。 目前,我有以下可行的方法:

@IBOutlet weak var textField: UITextField!
@IBOutlet weak var textLabal: UILabel!

​func writeSomeText(string: String, toOutput: UITextField) {
   // do some text processing
   toOutput.text = // processed string
}

​func writeSomeText(string: String, toOutput: UILabel) {
   // do some text processing
   toOutput.text = // processed string
}

如您所見,現在我正在重載該函數,實質上是為UITextField和UILabel復制了該函數,並且由於我有一堆完全相同的文本處理,因此我正在復制代碼。

有沒有什么方法可以使用泛型編寫一個函數來實現一個函數定義呢?

嘗試看看這種方法...

import UIKit

protocol P {
    func foo(str: String)->String
}
extension P {
    func foo(str: String)->String {
        // do some processing
        let res = str
        return res
    }
}
extension UILabel:P {
    func bar(str: String) {
        self.text = foo(str)
    }
}
extension UITextField:P {
    func bar(str: String) {
        self.text = foo(str)
    }
}

let l = UILabel()
l.text = "alfa"
l.bar("ALFA")

let t = UITextField()
t.text = "beta"
t.bar("BETA")

print(l.text, t.text) // Optional("ALFA") Optional("BETA")

順便說一句,您根本不需要協議P :-),它就像一個“命名空間”一樣(沒有全局func foo)

另一種方法是定義一些通用協議並擴展UILabel和UITextField

import UIKit

protocol P: class {
    var text: String? {get set}
}

extension UILabel: P {}
extension UITextField: P {}

func writeSomeText<T:P>(string: String, toOutput: T ){
    // do some text processing
    toOutput.text = string
}

let l = UILabel()
writeSomeText("label", toOutput: l)
l.text // "label"

let tv = UITextView()
tv.text = "text"
// but
writeSomeText("text view", toOutput: tv) // error: cannot invoke 'writeSomeText' with an argument list of type '(String, toOutput: UITextView)'

以后,如果需要,可以使用text屬性擴展其他類,而無需更改func writeSomeText的實現。

一個SWIFTY方式(不使用泛型)會

@objc
protocol UITextOutputProtocol: class {
    func setOutputText(text: String)
}

extension UITextField : UITextOutputProtocol {
    func setOutputText(text: String) {
        self.text = text
    }
}

extension UILabel : UITextOutputProtocol {
    func setOutputText(text: String) {
        self.text = text
    }
}

class ViewController: UIViewController {
    //An outlet Collection containing Labels and TextField
    @IBOutlet var texts: [UITextOutputProtocol]!

    //An example function that will be replicating a text in all controls
    func setTexts() {
        for text in texts {
            text.setOutputText("example Text")
        }
    }

更新:

由於UILabelUITextField現在正在實現協議UITextOutputProtocol因此以下代碼將起作用。

   @IBOutlet weak var textField: UITextField!
   @IBOutlet weak var textLabel: UILabel!

   ​func writeSomeText(string: String, toOutput: UITextOutputProtocol) {
     // do some text processing
     toOutput.setOutputText("example Text") // change the text here for your processed string
   }

   func doSomeProcessingOnText(text:String) {
     writeSomeText(text, textField)
     writeSomeText(text, textLabel)
   }
}

由於UITextFieldUILabel不遵循任何共享協議進行文本編輯,因此這有點麻煩,但是您可以使用KVO:

func writeSomeText(string: String, output: AnyObject) {
    // do some text processing
    if output.respondsToSelector("text") {
        output.setValue(string, forKey: "text")
    }
}

respondsToSelector檢查,以確保你傳遞的對象有一個屬性text繼續設置一個值,鍵之前。 如果您傳遞的密鑰文本不兼容KVO,則此檢查用於防止運行時崩潰。

暫無
暫無

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

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