Technically it does work(!), but I am hesitant to use it in what amounts to sample code for my current job search, haha.
On Sun, Jun 4, 2017 at 4:55 AM, Zhao Xin <owe...@gmail.com> wrote: > Will this work? > > class TapGestureRecognizer: UITapGestureRecognizer { > > var onTap: (() -> Void)? > > init(onTap: (() -> Void)?) { > > self.onTap = onTap > > super.init(target: nil, action: nil) > > * self.removeTarget(nil, action: nil)* > > self.addTarget(self, action: #selector(internalTapHandler)) > > print(self) > > } > > > > @objc private func internalTapHandler() { > > onTap?() > > } > > } > > Zhao Xin > > On Sun, Jun 4, 2017 at 5:24 PM, Nate Birkholz <nbirkh...@gmail.com> wrote: > >> Also, note that I tried the following: >> >> class BlockTapGestureRecognizer: UIGestureRecognizer { >> var onTap: (() -> Void)? >> init(onTap: (() -> Void)?) { >> self.onTap = onTap >> super.init(target: nil, action: nil) >> self.addTarget(self, action: #selector(internalTapHandler)) >> print(self) >> } >> >> @objc private func internalTapHandler() { >> onTap?() >> } >> } >> >> And the object prints looking okay: >> >> <Artmospherez.BlockTapGestureRecognizer: 0x1701998b0; baseClass = >> UIGestureRecognizer; state = Possible; view = <UIView 0x100c60870>; target= >> <(action=internalTapHandler, target=<Artmospherez.BlockTapGestureRecognizer >> 0x1701998b0>)>> >> >> But it doesn't in practice work. The documentation for the (target: >> action:) initializer states: >> >> target: An object that is the recipient of action messages sent by the >> receiver when it recognizes a gesture. nil is not a valid value. >> action: A selector that identifies the method implemented by the target >> to handle the gesture recognized by the receiver. The action selector must >> conform to the signature described in the class overview. NULL is not a >> valid value. >> >> So something is going on inside there when the nil values are passed to >> the recognizer. As the documentation states, nil is not a valid value and >> it must cause troubles. >> >> Or I did something wrong? >> >> >> >> On Sun, Jun 4, 2017 at 1:55 AM, Nate Birkholz <nbirkh...@gmail.com> >> wrote: >> >>> 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 <nbirkh...@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 <geo...@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@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 <owe...@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@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@swift.org >>>>>>> https://lists.swift.org/mailman/listinfo/swift-users >>>>>>> >>>>>>> >>>>>> >>>>> >>>>> >>>>> -- >>>>> Nate Birkholz >>>>> _______________________________________________ >>>>> swift-users mailing list >>>>> swift-users@swift.org >>>>> https://lists.swift.org/mailman/listinfo/swift-users >>>>> >>>> >>> >>> >>> -- >>> Nate Birkholz >>> >> >> >> >> -- >> Nate Birkholz >> > > -- Nate Birkholz
_______________________________________________ swift-users mailing list swift-users@swift.org https://lists.swift.org/mailman/listinfo/swift-users