I want to make a selector
argument of my method refer to a closure property, both of them exist in the same scope. For example,
func backgroundC
I tried this for UIBarButtonItem at least:
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()
}
}
Then you can do this:
navigationItem.leftBarButtonItem = UIBarButtonItem(title: "Test", style: .plain, action: {
print("Hello World!")
})
First of all, you need to declare an "easy to use" typealias
for your block:
typealias Completion = () -> ()
Then, you must declare private var to use "as a gate" for your function:
private var action: Completion?
After that, you should create a function that can be called by your Selector
(it accept only string format) and to call private completion:
@objc func didAction() {
self.action?()
}
Finally you can re-write your function (using the new swift syntax) like:
Timer.scheduledTimer(timeInterval: 0.5, target: self, selector: #selector(didAction), userInfo: nil, repeats: false)
self.action = backToOriginalBackground
P.S.: Remember that your variable (or parameter if you embed it to a function) must be of the same of type declared to your typeAlias
so, in our case:
var backToOriginalBackground: () -> ()
or also:
var backToOriginalBackground: Completion
No, #selector refers to an Objective-C method.
You can do something much better though: Add an extension to NSTimer that lets you create a scheduled timer not with a target and selector, but with a closure.
It is now possible. I've created a gist for block-based selectors in Swift 4.
https://gist.github.com/cprovatas/98ff940140c8744c4d1f3bcce7ba4543
Usage:
UIButton().addTarget(Selector, action: Selector { debugPrint("my code here") }, for: .touchUpInside)`
My solution was to create a class block variable like:
let completionBlock: () -> () = nil
Create a method which calls this completionBlock:
func completed(){
self.completionBlock!()
}
And inside where I want to put my selector like a block I did:
func myFunc(){
self.completionBlock = {//what I want to be done}
NSTimer.scheduledTimerWithTimeInterval(0.5, target: self, selector: #selector(Myclass.completed), userInfo: nil, repeats: false)
}