In my app Artmospherez, I recently found myself wanting to have gestures and buttons that would work in default implementations of a protocol. Unfortunately, UIButton and UIGestureRecognizer subclasses require the methods they call to be marked @objc to expose them to the Objective-C dynamic runtime to work. And in a Swift protocol extension, you cannot mark a method with @objc.
I had been wanting to experiment with closure-based buttons and gestures for some time, and this was my chance! The button case was relatively easy:
And to use it:
This works very well. You could also use a typealias for the closure signature ()->() if you wanted but I find it easier to read the code this way.
The tap handler was much trickier, and to be honest, I didn’t solve it myself. I asked about the original problem on the Swift Users email list, and list member “Geordie J” answered with a super slick reply using generics in a way that had I hadn’t thought of while working on a solution, and one that I will use widely from now on:
And in use:
Pretty happy with the way these solved my problem — letting me reduce code duplication via default implementations of my protocol — and also being fun to use. Thanks to Geordie and the Swift Users list for the help!