Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/symfony/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 要输出到UITextField或UILabel的通用函数_Ios_Swift_Generics_Swift2 - Fatal编程技术网

Ios 要输出到UITextField或UILabel的通用函数

Ios 要输出到UITextField或UILabel的通用函数,ios,swift,generics,swift2,Ios,Swift,Generics,Swift2,我正在尝试用Swift 2 for iOS编写一个函数,该函数处理一些文本并将其写入UITextField或UILabel。目前,我有以下几项工作: @IBOutlet weak var textField: UITextField! @IBOutlet weak var textLabal: UILabel! ​func writeSomeText(string: String, toOutput: UITextField) { // do some text processing

我正在尝试用Swift 2 for iOS编写一个函数,该函数处理一些文本并将其写入
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复制它,并且因为我有一堆完全相同的文本处理,所以我正在复制代码


是否有任何方法可以使用泛型编写一个函数,从而通过一个函数定义实现这一点?

这是一个小技巧,因为
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不兼容的对象时导致运行时崩溃。

这有点像黑客,因为
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不兼容,则此检查用于防止运行时崩溃。请尝试使用此方法

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)'
导入UIKit
协议P:类{
变量文本:字符串?{get set}
}
扩展UILabel:P{}
扩展UITextField:P{}
func writeSomeText(字符串:字符串,输出:T){
//做一些文本处理
toOutput.text=字符串
}
设l=UILabel()
WriteMetext(“标签”,输出:l)
l、 text/“标签”
让tv=UITextView()
tv.text=“text”
//但是
WriteMetext(“文本视图”,toOutput:tv)//错误:无法使用类型为“(字符串,toOutput:UITextView)”的参数列表调用“WriteMetext”

以后,如果需要,可以使用text属性扩展其他类。。。在不改变func WriteMetext的实现的情况下,尝试一下这种方法

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)'
导入UIKit
协议P:类{
变量文本:字符串?{get set}
}
扩展UILabel:P{}
扩展UITextField:P{}
func writeSomeText(字符串:字符串,输出:T){
//做一些文本处理
toOutput.text=字符串
}
设l=UILabel()
WriteMetext(“标签”,输出:l)
l、 text/“标签”
让tv=UITextView()
tv.text=“text”
//但是
WriteMetext(“文本视图”,toOutput:tv)//错误:无法使用类型为“(字符串,toOutput:UITextView)”的参数列表调用“WriteMetext”

以后,如果需要,可以使用text属性扩展其他类。。。如果不改变func WriteMetext的实现,一种快速的方式(没有泛型)将是

@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
现在正在实施协议
uitextutprotocol
,以下代码将起作用

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

一种快速的方法(没有泛型)是

@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
现在正在实施协议
uitextutprotocol
,以下代码将起作用

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

当然有,写一个协议,它有一个可设置的文本属性,使你的第二个参数成为一个符合这个协议的对象。当然有,写一个协议,它有一个可设置的文本属性,使你的第二个参数成为一个符合这个协议的对象。所以UITextView是另一个“候选对象”,不是吗?我不是Cocoa或CoCoatTouch的专家,但可能有一个较长的具有文本属性的对象列表,但这个问题不是关于
UITextView
(至少根据OP)。理论上,这个答案适用于任何包含
text
属性(字符串)的对象。如果
output
是一个具有
text
属性的对象,而该属性不是字符串,则会崩溃。因此,UITextView是另一个“候选对象”,不是吗?我不是Cocoa或CoCoatTouch的专家,但可能有一个较长的具有文本属性的对象列表,但这个问题不是关于
UITextView
(至少根据OP)。理论上,这个答案适用于任何包含
text
属性(字符串)的对象。如果
output
是一个具有
text
属性的对象,而该属性不是String.Hugo,那么这会崩溃,“…因为我有一堆完全相同的文本处理,所以我正在复制代码…”?以及@IBOutlet var text:[UITextOutputProtocol]的工作原理!如何在storyboard中创建它???这只是一个例子,在storyboard中,我只是将一个标签和一个文本字段链接到OutletCollection。Hugo,那么“…因为我有一堆完全相同的文本处理,我正在复制代码…”呢?以及@IBOutlet var text:[UITextOutputProtocol]的工作原理!如何在storyboard中创建它???这只是一个例子,在storyboard中,我只是将一个标签和一个文本字段链接到OutletCollection。这是一个很好的解决方案,效果非常好。非常感谢!欢迎您:-),如果您对我的答案感到满意,欢迎您接受,tooThis是一个很好的解决方案,工作非常完美。非常感谢!欢迎:-),如果你对我的回答满意,也欢迎你接受