我想以编程方式更改所有子视图的特定类类型(UILabel
,UITextField
等)的文本颜色(不仅仅是直接的孩子,还有那个孩子的孩子等等。
我创建了UIView
的扩展程序,以递归方式访问其所有子视图及其子视图。它目前硬编码为更改单一类型(UILabel
)的颜色。
这是我得到的代码:
import UIKit
extension UIView {
func setLabelTextColor(color: UIColor) {
for subview in self.subviews {
// Visit any subviews of the current subview (this is the recursive part)
subview.setLabelTextColor(color)
// Is this a label? If so, change it's text color.
if let label = subview as? UILabel { <-- I WANT TO PASS THIS CLASS
label.textColor = color
}
}
}
}
class OptimusPrimeViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
self.view.setLabelTextColor(UIColor.blueColor())
}
}
如何在Swift中使用泛型来传递类类型(如UITextField
而不是UILabel
),这样我就可以指定要更改哪个类'文本颜色?也许有一些块(封闭)魔法可以做同样的事情?
所以而不是:
self.view.setLabelTextColor(UIColor.blueColor())
我有类似的东西:
self.view.setTextColor(UIColor.blueColor(), forClassType: UITextField.self)
答案 0 :(得分:2)
您可以在函数定义中定义泛型类型T
,如下所示:
extension UIView {
func setTextColor<T: UIView>(color: UIColor, forClassType _: T.Type) {
for subview in self.subviews as [UIView] {
subview.setTextColor(color, forClassType: T.self)
if let view = subview as? T {
view.textColor = color
}
}
}
}
但是,textColor
不是所有UIView
的属性,因此您需要更进一步。一种解决方案是定义具有textColor
属性的协议,然后声明UILabel
,UITextField
以及要与此函数一起使用的任何其他类的协议一致性。如果该类尚未定义textColor
属性,则需要将其添加到扩展名中。
所以这是完整的代码:
protocol HasTextColor {
var textColor: UIColor! { get set }
}
extension UILabel: HasTextColor {}
extension UITextField: HasTextColor {}
extension UIView {
func setTextColor<T: UIView where T: HasTextColor>(color: UIColor, forClassType _: T.Type) {
for subview in self.subviews as [UIView] {
subview.setTextColor(color, forClassType: T.self)
if let view = subview as? T {
view.textColor = color
}
}
}
}
您可以完全按照建议调用此函数:
self.view.setTextColor(UIColor.blueColor(), forClassType: UITextField.self)
答案 1 :(得分:0)
我想我找到了一种方法来做到这一点,而不必使用协议,并且必须明确地将每个类符合该协议,以便他们可以使用此功能。
相反,它使用NOSbject内省来查看视图是否是正确的类型并具有该属性。这样我可以将它与任何具有textColor的东西一起使用,并且不必添加任何代码。
func setGlobalTextColor<T: NSObject>(color: UIColor, forClassType: T.Type) {
for subview in self.subviews as [UIView]{
// Visit every child before applying changes
subview.setGlobalTextColor(color, forClassType: T.self)
// Only change text color for the class we called the function with
if subview.isMemberOfClass(T) {
// Sanity check to make sure we only set if class has this property
if subview.respondsToSelector(Selector("textColor")) {
// Use Key Value Coding to set the textColor
subview.setValue(color, forKey: "textColor")
}
}
}
}
因此,您可以使用具有UIColor textColor属性的不同类来调用它:
self.view.setTextColor(UIColor.blueColor(), forClassType: UILabel.self)
self.view.setTextColor(UIColor.redColor(), forClassType: UITextField.self)