Dynamic 在Swift中,如何使用setValueForKey设置对象的textAlignment属性?
假设我们定义这样一个对象:Dynamic 在Swift中,如何使用setValueForKey设置对象的textAlignment属性?,dynamic,reflection,swift,Dynamic,Reflection,Swift,假设我们定义这样一个对象: let object: AnyObject = { var result = UILabel(frame: CGRect(x: 0, y: 0, width: 150, height: 50)) result.text = "First Text" result.backgroundColor = UIColor.blueColor() return result }() (object as UILabel).text = "S
let object: AnyObject = {
var result = UILabel(frame: CGRect(x: 0, y: 0, width: 150, height: 50))
result.text = "First Text"
result.backgroundColor = UIColor.blueColor()
return result
}()
(object as UILabel).text = "Second Text"
object.setValue(NSTextAlignment.Center, forKey: "textAlignment")
对于这个例子,我显式地创建了一个UILabel
,但是在我的实际项目中,我不知道创建了什么类型的对象,所以对于这个例子,我只是将结果视为AnyObject
。该对象只是一个标准的UILabel,蓝色背景上有“第一个文本”的文本,默认向左对齐
在本例中,我知道该对象实际上是一个UILabel
,因此我知道可以像这样更改其属性:
let object: AnyObject = {
var result = UILabel(frame: CGRect(x: 0, y: 0, width: 150, height: 50))
result.text = "First Text"
result.backgroundColor = UIColor.blueColor()
return result
}()
(object as UILabel).text = "Second Text"
object.setValue(NSTextAlignment.Center, forKey: "textAlignment")
现在我改变了文本。但是在我的实际项目中,我不知道我的对象是一个UILabel
,所以我不能只做(对象作为UILabel)
,因为它并不总是UILabel
。我的解决方法是使用setValueForKey
。使用respondsToSelector
(本例中未显示)检查我的对象是否有名为“text”的成员后,我可以通过以下方式更改文本:
object.setValue("Third Text", forKey: "text")
现在,如果我想更改对象的textAlignment
,在检查对象是否确实有名为textAlignment
的成员后,我想做如下操作:
let object: AnyObject = {
var result = UILabel(frame: CGRect(x: 0, y: 0, width: 150, height: 50))
result.text = "First Text"
result.backgroundColor = UIColor.blueColor()
return result
}()
(object as UILabel).text = "Second Text"
object.setValue(NSTextAlignment.Center, forKey: "textAlignment")
但这样做会导致错误:
Type 'NSTextAlignment' does not conform to protocol 'AnyObject'
我在尝试设置帧时遇到了类似的情况,因为它不喜欢CGRect
类型,但我可以通过将CGRect
转换为NSValue
来绕过它。但是,对于enum
类型,如NSTextAlignment
,我找不到修复它的方法
有人知道我如何在这里实现我的目标吗?您必须使用原始值NSTextAlignment.Center.rawValue
object.setValue(NSTextAlignment.Center.rawValue, forKey: "textAlignment")
必须使用原始值NSTextAlignment.Center.rawValue
object.setValue(NSTextAlignment.Center.rawValue, forKey: "textAlignment")
另一种选择是声明一个具有您感兴趣的属性的协议,然后扩展您想要使用的类型以采用该协议。如果在这种情况下这样做对您有效,那么它似乎更安全。另一种选择是使用您感兴趣的属性声明一个协议,然后扩展要使用的类型以采用该协议。在这种情况下,如果这样做对您有效,它似乎更安全。虽然协议方法似乎更安全,但事实是,我不知道将使用哪些属性,因为我不知道正在使用哪些对象。一切都是在运行时动态发生的,所以我真的无法为属性本身实现任何静态冷。我能做的最远的事情就是实现从动态值(字符串文本)到他们试图设置的属性的任何类型的转换函数。虽然协议方法似乎更安全,但事实是我不知道将使用什么属性,因为我不知道正在使用什么对象。一切都是在运行时动态发生的,所以我真的无法为属性本身实现任何静态冷。我能做的最远的事情就是实现从动态值(字符串文本)到他们试图设置的属性的任何类型的转换函数。这太完美了!我看了rawValue一点,但我没意识到我可以用这个。我试图使用它来调用NSTextAlignment
,但我又回到了将枚举传递给setValueForKey的位置。这很好用,真是太好了!我看了rawValue一点,但我没意识到我可以用这个。我试图使用它来调用NSTextAlignment
,但我又回到了将枚举传递给setValueForKey的位置。这很有效。