In Swift you can create a function for a button like this:
button.addTarget(self, action: #selector(buttonAction), forControlEvents: .TouchUpInside)
However is there a way I can do something like this:
button.whenButtonIsClicked({Insert code here})
That way I do not even have too declare an explicit function for the button. I know I can use button tags but I would prefer to do this instead.
This one will work ! Make sure you don't alter the tag for buttons
}
Create your own
UIButton
subclass to do this:Substitute
MyButton
forUIButton
when you create buttons programmatically and then callwhenButtonIsClicked
to set up its functionality.You can also use this with
UIButton
s in a Storyboard (just change their class toMyButton
) and then callwhenButtonIsClicked
inviewDidLoad
.A much more capable implementation
Recognizing the fact that programmers might want to handle more events than just
.touchUpInside
, I wrote this more capable version which supports multiple closures perUIButton
and multiple closures per event type.Demo
If you don't want to do anything "questionable" (i.e., using Objective-C's dynamic capabilities, or adding your own touch handlers, etc.) and do this purely in Swift, unfortunately this is not possible.
Any time you see
#selector
in Swift, the compiler is callingobjc_MsgSend
under the hood. Swift doesn't support Objective-C's dynamicism. For better or for worse, this means that in order to swap out the usage of this selector with a block, you'd probably need to perform some black magic to make it work, and you'd have to use Objective-C constructs to do that.If you don't have any qualms about doing "yucky dynamic Objective-C stuff", you could probably implement this by defining an extension on
UIButton
, and then associate a function to the object dynamically using associated objects. I'm going to stop here, but if you want to read more, NSHipster has a great overview on associated objects and how to use them.You can also just subclass
UIView
and have a property that is a closure like vacawama has.Then override the
touchesBegan
method to call the function whenever the button is touched. With this approach though you don't get all the benefits of starting with a UIBitton.