[swift-users] Calling default implementation of protocol methods as selectors

Nate Birkholz nbirkholz at gmail.com
Sun Jun 4 03:55:05 CDT 2017


Ah, I didn't read the rest of the thread. As Zhao Xin notes, you cannot
call super.init(target: self, action: #selector()), and you cannot call
super.init() in a subclass init or convenience init, it *has* to be the
designated init method init(target:action:). That's too bad, closure-based
gesture recognizers would be snazzy and swifty and I'd love to see them as
part of UIKit.

I could write my own custom implementations of subclassed
UIKit.UIGestureRecognizerSubclass(es), but as the screens in question have
tap, swipe up, swipe down, and swipe right gesture recognizers, I feel its
overkill to write all that to avoid repeating ~10 lines of code.

On Sun, Jun 4, 2017 at 1:21 AM, Nate Birkholz <nbirkholz at gmail.com> wrote:

> I briefly considered something like this but didn't explore it. Elegant.
>
> Sent from my iPhone, please excuse brevity and errors
>
> On Jun 3, 2017, at 9:38 PM, Geordie Jay <geojay at gmail.com> wrote:
>
> I am dealing with a variant of this on Android right now. I have just
> subclassed e.g. UITapGestureRecognizer to perform the 2nd variant above and
> externally accept a closure as its argument. I'm writing this on my phone
> so forgive any syntax errors or accidental omissions:
>
> class TapGestureRecognizer: UITapGestureRecognizer {
> var onTap: (() -> Void)?
> init(onTap: (() -> Void)?) {
> self.onTap = onTap
> super.init(target: self, action: #selector(internalTapHandler))
> }
>
> @objc private func internalTapHandler() {
> onTap?()
> }
> }
>
> class Baz: Foo {
> init() {
> let tapRecognizer = TapGestureRecognizer(onTap: self.bar)
> }
> }
>
>
> Cheers,
> Geordie
> On Sat 3. Jun 2017 at 16:53, Nate Birkholz via swift-users <
> swift-users at swift.org> wrote:
>
>> Thanks, the second had occurred to me, but felt a little too much like in
>> practice it would make the code harder to understand.
>>
>> On Fri, Jun 2, 2017 at 9:58 PM, Zhao Xin <owenzx at gmail.com> wrote:
>>
>>> I found two workarounds.
>>>
>>> 1.
>>>
>>> protocol Foo: class {
>>>
>>>     func bar()
>>>
>>> }
>>>
>>>
>>> class Base:Foo {
>>>
>>>     @objc func bar() {
>>>
>>>         print("bar")
>>>
>>>     }
>>>
>>> }
>>>
>>>
>>> class Baz: Base {
>>>
>>>     override init() {
>>>
>>>         super.init()
>>>
>>>         let tapRecognizer = UITapGestureRecognizer(target: self,
>>> action: #selector(bar))
>>>
>>>     }
>>>
>>> }
>>>
>>> 2.
>>>
>>> protocol Foo: class {
>>>
>>>     func bar()
>>>
>>> }
>>>
>>>
>>> extension Foo {
>>>
>>>     func bar() {
>>>
>>>         print("bar")
>>>
>>>     }
>>>
>>> }
>>>
>>>
>>> class Baz: Foo {
>>>
>>>     init() {
>>>
>>>         let tapRecognizer = UITapGestureRecognizer(target: self,
>>> action: #selector(delegate))
>>>
>>>     }
>>>
>>>
>>>
>>>     @objc func delegate() {
>>>
>>>         bar()
>>>
>>>     }
>>>
>>> }
>>>
>>>
>>> Zhao Xin
>>>
>>>
>>>
>>>
>>>
>>>
>>> On Sat, Jun 3, 2017 at 10:35 AM, Nate Birkholz via swift-users <
>>> swift-users at swift.org> wrote:
>>>
>>>> protocol Foo: class {
>>>>     func bar()
>>>> }
>>>>
>>>> extension Foo {
>>>>     func bar() {
>>>>          print("bar")
>>>>     }
>>>> }
>>>>
>>>> class Baz: Foo {
>>>>     init() {
>>>>         let tapRecognizer = UITapGestureRecognizer(target: self,
>>>> action: #selector(bar))
>>>>     }
>>>> }
>>>>
>>>> the #selector tells me: "Argument of '#selector' refers to instance
>>>> method 'bar()' that is not exposed to Objective-C" and asks me to add @objc
>>>> to the method definition.
>>>>
>>>> Adding @objc to the method tells me: "@objc can only be used with
>>>> members of classes, @objc protocols, and concrete extensions of classes"
>>>>
>>>> Adding @objc to the protocol doesn't fix it, just introduces new issues.
>>>>
>>>> "dynamic" cannot be applied to a protocol, so cannot be used
>>>> alternatively.
>>>>
>>>> Is there a way to get around this? If a method is called by a gesture
>>>> recognizer, is there no way to have a default protocol implementation? I'd
>>>> like to use default implementations if possible to make my code more DRY.
>>>>
>>>> Is there a roadmap/plan for swift-native selector dispatch?
>>>>
>>>> Thanks. I look forward to the inevitable reply revealing the dumb thing
>>>> I missed. :)
>>>>
>>>> --
>>>> Nate Birkholz
>>>>
>>>> _______________________________________________
>>>> swift-users mailing list
>>>> swift-users at swift.org
>>>> https://lists.swift.org/mailman/listinfo/swift-users
>>>>
>>>>
>>>
>>
>>
>> --
>> Nate Birkholz
>> _______________________________________________
>> swift-users mailing list
>> swift-users at swift.org
>> https://lists.swift.org/mailman/listinfo/swift-users
>>
>


-- 
Nate Birkholz
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-users/attachments/20170604/46df13aa/attachment.html>


More information about the swift-users mailing list