Bla*_*ard 23 closures selector swift
我想让selector我的方法的参数引用一个闭包属性,它们都存在于同一范围内.例如,
func backgroundChange() {
self.view.backgroundColor = UIColor.blackColor()
self.view.alpha = 0.55
let backToOriginalBackground = {
self.view.backgroundColor = UIColor.whiteColor()
self.view.alpha = 1.0
}
NSTimer.scheduledTimerWithTimeInterval(0.5, target: self, selector: #selector(backToOriginalBackground), userInfo: nil, repeats: false)
}
Run Code Online (Sandbox Code Playgroud)
但是,这显示错误:Argument of #selector cannot refer to a property.
当然,我可以定义一个新的,单独的方法并将闭包的实现移动到它,但我想为这么小的实现保持节俭.
是否可以设置闭包#selector参数?
wer*_*ver 29
不是直接的,但可能有一些变通方法.看一下下面的例子.
/// Target-Action helper.
final class Action: NSObject {
private let _action: () -> ()
init(action: @escaping () -> ()) {
_action = action
super.init()
}
@objc func action() {
_action()
}
}
let action1 = Action { print("action1 triggered") }
let button = UIButton()
button.addTarget(action1, action: #selector(action1.action), forControlEvents: .TouchUpInside)
Run Code Online (Sandbox Code Playgroud)
sch*_*her 11
我至少尝试过UIBarButtonItem:
private var actionKey: Void?
extension UIBarButtonItem {
private var _action: () -> () {
get {
return objc_getAssociatedObject(self, &actionKey) as! () -> ()
}
set {
objc_setAssociatedObject(self, &actionKey, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
}
}
convenience init(title: String?, style: UIBarButtonItemStyle, action: @escaping () -> ()) {
self.init(title: title, style: style, target: nil, action: #selector(pressed))
self.target = self
self._action = action
}
@objc private func pressed(sender: UIBarButtonItem) {
_action()
}
}
Run Code Online (Sandbox Code Playgroud)
然后你可以这样做:
navigationItem.leftBarButtonItem = UIBarButtonItem(title: "Test", style: .plain, action: {
print("Hello World!")
})
Run Code Online (Sandbox Code Playgroud)
正如@ gnasher729所指出的那样,这是不可能的,因为选择器只是方法的名称,而不是方法本身.在一般情况下,我会dispatch_after在这里使用,但在这种特殊情况下,更好的工具IMO UIView.animateWithDuration,因为它正是该功能的用途,并且很容易调整转换:
UIView.animateWithDuration(0, delay: 0.5, options: [], animations: {
self.view.backgroundColor = UIColor.whiteColor()
self.view.alpha = 1.0
}, completion: nil)
Run Code Online (Sandbox Code Playgroud)
现在有可能。我在Swift 4中为基于块的选择器创建了要点。
https://gist.github.com/cprovatas/98ff940140c8744c4d1f3bcce7ba4543
用法:
UIButton().addTarget(Selector, action: Selector { debugPrint("my code here") }, for: .touchUpInside)
| 归档时间: |
|
| 查看次数: |
14373 次 |
| 最近记录: |