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 >
_______________________________________________ swift-users mailing list swift-users@swift.org https://lists.swift.org/mailman/listinfo/swift-users