[swift-users] TWISt-shout Newsletter 2017-06-05

2017-06-04 Thread Kenny Leung via swift-users
Hi All.

Here is your TWISt-shout Newsletter for the week of 2017-05-29 to 2017-06-04

https://github.com/pepperdog/TWISt-shout/blob/master/2017/TWISt-shout-2017-06-05.md
 


Enjoy!

-Kenny


___
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users


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

2017-06-04 Thread Nate Birkholz via swift-users
That works great and is very elegant. Nice work.

On Sun, Jun 4, 2017 at 6:34 AM, Geordie J  wrote:

> In fact, this would be even better (avoids unnecessary implicitly
> unwrapped optionals):
>
> class ClosureGestureRecognizer {
> fileprivate var recognizer: GestureRecognizer
> private var onAction: ((GestureRecognizer) -> Void)
>
> init(onAction: @escaping ((GestureRecognizer) -> Void)) {
> self.recognizer = GestureRecognizer()
> self.onAction = onAction
>
> self.recognizer.addTarget(self, action: #selector(actionHandler))
> }
>
> @objc private func actionHandler() {
> onAction(recognizer)
> }
> }
>
> extension UIView {
> func addGestureRecognizer(_ gestureRecognizer:
> ClosureGestureRecognizer) {
> self.addGestureRecognizer(gestureRecognizer.recognizer)
> }
> }
>
> Depending on your use-case, it’d be no problem to make *onAction* a
> non-private (externally settable) optional closure—in case you want to
> avoid having to set it on init of ClosureGestureRecognizer.
>
> Cheers,
> Geordie
>
>
> Am 04.06.2017 um 23:09 schrieb Geordie J :
>
> To get around the issue of using self on init, but also that of multiple
> recogniser types, try this:
>
> class ClosureGestureRecognizer {
> // These are initially nil and set on init to their desired values.
> // This gets around the issue of using self in init.
> // `private` means they can't ever actually be nil:
> private var recognizer: RecognizerType!
> private var onAction: ((RecognizerType) -> Void)!
>
> init(callback: @escaping ((RecognizerType) -> Void)) {
> recognizer = RecognizerType(target: self, action: #selector(
> actionHandler))
> self.onAction = callback
> }
>
> @objc private func actionHandler() {
> onAction(recognizer)
> }
> }
>
> let recognizer = ClosureGestureRecognizer(callback:
> { panGestureRecognizer in
> print("Panned, translation:", panGestureRecognizer.translation(in: nil
> ))
> })
>
> Regards,
> Geordie
>
>
> Am 04.06.2017 um 21:55 schrieb Zhao Xin :
>
> 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  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:
>>
>> > UIGestureRecognizer; state = Possible; view = ; target=
>> <(action=internalTapHandler, target=> 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 
>> 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 
>>> wrote:
>>>
 I briefly considered something like this but didn't explore it. Elegant.

 Sent from my iPhone, please excuse 

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

2017-06-04 Thread Charles Srstka via swift-users
Here’s what I’d try.

(disclaimer: written in Mail, may contain errors, yadda yadda yadda)

public class BlockTapGestureRecognizer: UITapGestureRecognizer {
private class Target: NSObject {
private let closure: (UITapGestureRecognizer) -> ()

init(closure: @escaping (UITapGestureRecognizer) -> ()) {
self.closure = closure
super.init()
}

@objc func performClosure(_ sender: Any?) {
guard let recognizer = sender as? UITapGestureRecognizer else {
print("Unexpected sender (expected UITapGestureRecognizer)")
return
}

self.closure(recognizer)
}
}

private let target: Target

public init(closure: @escaping (UITapGestureRecognizer) -> ()) {
self.target = Target(closure: closure)
super.init(target: self.target, action: 
#selector(Target.performClosure(_:)))
}
}

No need for weird hacks passing nil as the target or action.

Charles

> On Jun 4, 2017, at 11:08 AM, Nate Birkholz via swift-users 
>  wrote:
> 
> 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  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  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:
> 
>  UIGestureRecognizer; state = Possible; view = ; target= 
> <(action=internalTapHandler, target= 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  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  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  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 

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

2017-06-04 Thread Nate Birkholz via swift-users
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  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  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:
>>
>> > UIGestureRecognizer; state = Possible; view = ; target=
>> <(action=internalTapHandler, target=> 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 
>> 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 
>>> 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  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  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")
>>

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

2017-06-04 Thread Geordie J via swift-users
In fact, this would be even better (avoids unnecessary implicitly unwrapped 
optionals):

class ClosureGestureRecognizer {
fileprivate var recognizer: GestureRecognizer
private var onAction: ((GestureRecognizer) -> Void)

init(onAction: @escaping ((GestureRecognizer) -> Void)) {
self.recognizer = GestureRecognizer()
self.onAction = onAction

self.recognizer.addTarget(self, action: #selector(actionHandler))
}

@objc private func actionHandler() {
onAction(recognizer)
}
}

extension UIView {
func addGestureRecognizer(_ gestureRecognizer: 
ClosureGestureRecognizer) {
self.addGestureRecognizer(gestureRecognizer.recognizer)
}
}

Depending on your use-case, it’d be no problem to make onAction a non-private 
(externally settable) optional closure—in case you want to avoid having to set 
it on init of ClosureGestureRecognizer.

Cheers,
Geordie


> Am 04.06.2017 um 23:09 schrieb Geordie J :
> 
> To get around the issue of using self on init, but also that of multiple 
> recogniser types, try this:
> 
> class ClosureGestureRecognizer {
> // These are initially nil and set on init to their desired values.
> // This gets around the issue of using self in init.
> // `private` means they can't ever actually be nil:
> private var recognizer: RecognizerType!
> private var onAction: ((RecognizerType) -> Void)!
> 
> init(callback: @escaping ((RecognizerType) -> Void)) {
> recognizer = RecognizerType(target: self, action: 
> #selector(actionHandler))
> self.onAction = callback
> }
> 
> @objc private func actionHandler() {
> onAction(recognizer)
> }
> }
> 
> let recognizer = ClosureGestureRecognizer(callback: { 
> panGestureRecognizer in
> print("Panned, translation:", panGestureRecognizer.translation(in: nil))
> })
> 
> Regards,
> Geordie
> 
> 
>> Am 04.06.2017 um 21:55 schrieb Zhao Xin > >:
>> 
>> 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 > > 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:
>> 
>> > UIGestureRecognizer; state = Possible; view = ; target= 
>> <(action=internalTapHandler, target=> 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 > > 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 > > wrote:
>> I briefly considered something like this but didn't explore it. Elegant.
>> 
>> Sent from my iPhone, please excuse brevity and 

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

2017-06-04 Thread Geordie J via swift-users
To get around the issue of using self on init, but also that of multiple 
recogniser types, try this:

class ClosureGestureRecognizer {
// These are initially nil and set on init to their desired values.
// This gets around the issue of using self in init.
// `private` means they can't ever actually be nil:
private var recognizer: RecognizerType!
private var onAction: ((RecognizerType) -> Void)!

init(callback: @escaping ((RecognizerType) -> Void)) {
recognizer = RecognizerType(target: self, action: 
#selector(actionHandler))
self.onAction = callback
}

@objc private func actionHandler() {
onAction(recognizer)
}
}

let recognizer = ClosureGestureRecognizer(callback: { 
panGestureRecognizer in
print("Panned, translation:", panGestureRecognizer.translation(in: nil))
})

Regards,
Geordie


> Am 04.06.2017 um 21:55 schrieb Zhao Xin :
> 
> 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  > 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:
> 
>  UIGestureRecognizer; state = Possible; view = ; target= 
> <(action=internalTapHandler, target= 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  > 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  > 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  > 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 
>> > 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 > 

Re: [swift-users] Optional binding with non-optional expression

2017-06-04 Thread Zhao Xin via swift-users
Then I knew it.

if let a: A = A() { // this is a warning as it treats like always true

print("something") // this line always runs

}

For

if let a = A() { // show an error as the compiler thinks you are missing
something.

}

For me, the first example, explicitly given the type of `a`, so it is a
warning. The second example, is one step farther than the first one. And it
is shown as an error.

Each one of them is correct by itself. But putting together, there is a
self-contradictory feeling.


Zhao Xin


On Sun, Jun 4, 2017 at 6:00 PM, Martin R  wrote:

> I don’t think that explains it (or perhaps I did not understand your
> response correctly).
>
> Here is the same issue with a custom type (which does not have a failable
> initializer):
>
>struct A { }
>
>if let a = A() { }
>// error: initializer for conditional binding must have Optional type,
> not 'A'
>
>if let a: A = A() { }
>// warning: non-optional expression of type 'A' used in a check for
> optionals
>
>
> > Am 02.06.2017 um 15:49 schrieb Zhao Xin :
> >
> > I think it did an unnecessary implicitly casting. For example,
> >
> > let y = Int(exactly: 5)
> > print(type(of:y)) // Optional
> >
> > You code equals to
> >
> > if let y:Int = Int(exactly: 5) { }
> >
> > However, I don't know why it did that. Maybe because of type inferring?
> >
> > Zhaoxin
> >
> > On Fri, Jun 2, 2017 at 8:40 PM, Martin R via swift-users <
> swift-users@swift.org> wrote:
> > This following code fails to compile (which is correct, as far as I can
> judge that):
> >
> >if let x = 5 { }
> >// error: initializer for conditional binding must have Optional
> type, not 'Int'
> >
> > But why is does it compile (with a warning) if an explicit type
> annotation is added?
> >
> >if let y: Int = 5 { }
> >// warning: non-optional expression of type 'Int' used in a check for
> optionals
> >
> > Tested with Xcode 8.3.2 and both the build-in Swift 3.1 toolchain and
> the Swift 4.0 snapshot from May 25, 2017.
> >
> > I am just curious and would like to understand if there is fundamental
> difference between those statements.
> >
> > Regards, Martin
> >
> >
> >
> > ___
> > swift-users mailing list
> > swift-users@swift.org
> > https://lists.swift.org/mailman/listinfo/swift-users
> >
> >
>
>
___
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users


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

2017-06-04 Thread Zhao Xin via swift-users
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  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:
>
>  UIGestureRecognizer; state = Possible; view = ; target=
> <(action=internalTapHandler, target= 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  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 
>> 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  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  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
>
>
>
>
>
>

Re: [swift-users] Optional binding with non-optional expression

2017-06-04 Thread Martin R via swift-users
I don’t think that explains it (or perhaps I did not understand your response 
correctly).

Here is the same issue with a custom type (which does not have a failable 
initializer):

   struct A { }

   if let a = A() { }
   // error: initializer for conditional binding must have Optional type, not 
'A' 

   if let a: A = A() { }
   // warning: non-optional expression of type 'A' used in a check for optionals


> Am 02.06.2017 um 15:49 schrieb Zhao Xin :
> 
> I think it did an unnecessary implicitly casting. For example,
> 
> let y = Int(exactly: 5)
> print(type(of:y)) // Optional
> 
> You code equals to
> 
> if let y:Int = Int(exactly: 5) { }
> 
> However, I don't know why it did that. Maybe because of type inferring?
> 
> Zhaoxin
> 
> On Fri, Jun 2, 2017 at 8:40 PM, Martin R via swift-users 
>  wrote:
> This following code fails to compile (which is correct, as far as I can judge 
> that):
> 
>if let x = 5 { }
>// error: initializer for conditional binding must have Optional type, not 
> 'Int'
> 
> But why is does it compile (with a warning) if an explicit type annotation is 
> added?
> 
>if let y: Int = 5 { }
>// warning: non-optional expression of type 'Int' used in a check for 
> optionals
> 
> Tested with Xcode 8.3.2 and both the build-in Swift 3.1 toolchain and the 
> Swift 4.0 snapshot from May 25, 2017.
> 
> I am just curious and would like to understand if there is fundamental 
> difference between those statements.
> 
> Regards, Martin
> 
> 
> 
> ___
> swift-users mailing list
> swift-users@swift.org
> https://lists.swift.org/mailman/listinfo/swift-users
> 
> 

___
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users


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

2017-06-04 Thread Nate Birkholz via swift-users
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:

; target=
<(action=internalTapHandler, target=)>>

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  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  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  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  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 

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

2017-06-04 Thread Nate Birkholz via swift-users
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  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  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  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
___
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users


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

2017-06-04 Thread Nate Birkholz via swift-users
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  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 
>>  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  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 
  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
___
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users