I have a generic control class which needs to set the completion of the button depending on the view controller.Due to that setLeftButtonActionWithClosure function needs to take as parameter a closure which should be set as action to an unbutton.How would it be possible in Swift since we need to pass the function name as String to action: parameter.
func setLeftButtonActionWithClosure(completion: () -> Void)
{
self.leftButton.addTarget(<#target: AnyObject?#>, action: <#Selector#>, forControlEvents: <#UIControlEvents#>)
}
NOTE: like @EthanHuang said "This solution doesn't work if you have more than two instances. All actions will be overwrite by the last assignment." Keep in mind this when you develop, i will post another solution soon.
If you want to add a closure as target to a
UIButton
, you must add a function toUIButton
class by usingextension
and the call:
One more optimisation (useful if you use it in many places and don't want to duplicate call to
objc_setAssociatedObject
). It allows us to not worry about a dirty part ofobjc_setAssociatedObject
and keeps it insideClosureSleeve
's constructor:So your extension will look a tiny bit cleaner:
This is basically Armanoide's answer, above, but with a couple slight changes that are useful for me:
UIButton
argument, allowing you to pass inself
the functions and arguments are renamed in a way that, for me, clarifies what's going on, for instance by distinguishing a Swift closure from a
UIButton
action.Much props to Armanoide though for some heavy-duty magic here.
I have started to use Armanoide's answer disregarding the fact that it'll be overridden by the second assignment, mainly because at first I needed it somewhere specific which it didn't matter much. But it started to fall apart.
I've came up with a new implementation using AssicatedObjects which doesn't have this limitation, I think has a smarter syntax, but it's not a complete solution:
Here it is:
As you can see, I've decided to make a dedicated case for
touchUpInside
. I know controls have more events than this one, but who are we kidding? do we need actions for every one of them?! It's much simpler this way.Usage example:
In any case, if you want to extend this answer you can either make a
Set
of actions for all the event types, or add more event's properties for other events, it's relatively straightforward.Cheers, M.
You can effectively achieve this by subclassing UIButton:
Use: