![](/img/trans.png)
[英]UILabel in UIAlertController or UITextField alike 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")
}
}
更新:
由於UILabel
和UITextField
現在正在實現協議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)
}
}
由於UITextField
和UILabel
不遵循任何共享協議進行文本編輯,因此這有點麻煩,但是您可以使用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.