在一段代码中,我想动态地在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对象的转换,但我不知道如何以通用的方式解决这个问题。
这是斯威夫特2的正确方法吗,还是有人在我的理论中发现了一个简单的错误?
发布于 2016-01-10 18:58:22
我在附近玩了一会儿就找到了解决办法。我注意到了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)
}
}https://stackoverflow.com/questions/34704595
复制相似问题