在我动态想要在UIButton上触发方法的一段代码中,我想执行提供UIControlState的方法。
例如,我现在的代码是:
private func setValue(value: AnyObject, forKey: String, forState: UIControlState) {
let methodName = "set" + forKey.capitalizedString + ":forState:"
let sel = Selector(methodName)
if self.respondsToSelector(sel) {
self.performSelector(sel, withObject: value, withObject: forState.rawValue)
}
}
在此示例中,forKey
包含Title
,forState
包含UIControlState.Normal
。 value
只是一个简单的字符串,但定义为AnyObject
。它接受AnyObject
,因为还有一些方法需要UIImage等。
self
是UIButton
。
UIButton
确实回复我创建的Selector
(定义为setTitle:forState:
),并触发performSelector
方法任何警告,但仍然没有更新此UIButton的标题。
问题可能在于value
对象形式AnyObject
转换为String
或转换forState
对象,但我不知道如何我可以通用的方式解决这个问题。
这是从Swift 2执行此操作的正确方法,还是有人在我的理论中发现了一个简单的错误?
答案 0 :(得分:1)
我找到了解决方案后,有点鬼混。我注意到methodForSelector
方法并发现,使用IMP是我的问题的解决方案。
private func setValue(value: AnyObject, forKey key: String, forState state: UIControlState) {
let methodName = "set" + key.capitalizedString + ":forState:"
let sel = Selector(methodName)
if self.respondsToSelector(sel) {
typealias setValueForControlStateIMP = @convention(c) (UIView, Selector, AnyObject, UIControlState) -> Void
let methodSignature = self.methodForSelector(sel)
let callback = unsafeBitCast(methodSignature, setValueForControlStateIMP.self)
callback(self, sel, value, state)
}
}