Fattie
Fattie

Reputation: 12582

Swift 3 needs more info, to infer a parameter?

I have an extension which bubbles upwards,

but in Swift 3,

Generic parameter 'T' could not be inferred

public extension UIResponder
    {
    public func next<T>() -> T?
        {
        guard let responder = self.next
            else { return nil }
        return (responder as? T) ?? responder.next()
        }
    }

 // note - kudos to this excellent post:
 // https://blog.veloxdb.com/2016/05/12/bubbling-events-using-uiresponder-in-swift/

in Swift<3, you could use that like this:

class SnapDot:UIView 
    {
    .....
    func handleTap(g:UITapGestureRecognizer)
        {
        (next() as Snap?)?.oneDotWasClicked(self)
        }

I'm afraid that not only (a) I can't see why it wouldn't be inferred in Swift 3, but (b) even by endlessly trying random variations, I can't get it to work in Swift 3 :O

Upvotes: 2

Views: 160

Answers (1)

Martin R
Martin R

Reputation: 539685

That is a name collision between the existing next method of UIResponder, and your extension method. self.next inside your method refers to the (generic) method itself.

Renaming the extension makes it compile:

public extension UIResponder {
    public func nextOfType<T>() -> T? {
        guard let responder = self.next
            else { return nil }
        return (responder as? T) ?? responder.nextOfType()
    }
}

And even if you didn't ask for it, here is an iterative instead of recursive version :)

public extension UIResponder {
    public func nextOfType<T>() -> T? {
        var current = self
        while let responder = current.next {
            if let match = responder as? T {
                return match
            }
            current = responder
        }
        return nil
    }
}

Upvotes: 3

Related Questions