Valentin Shamardin
Valentin Shamardin

Reputation: 3658

Extend swift class that already conforms some protocol

I have some class (class A: UIView) that conforms protocol UIGestureRecognizerDelegate from third-party library. I need to extend this class by adding some optional UIGestureRecognizerDelegate method, for example gestureRecognizer:shouldRequireFailureOfGestureRecognizer:. How to do that?

I have tried writing an extension for A:

extension A {
    func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRequireFailureOf otherGestureRecognizer: UIGestureRecognizer) -> Bool {
        print("abcd") // BREAKPOINT NOT REACHABLE
    }
}

Then an extension for a protocol (even without Self == A):

extension UIGestureRecognizer where Self == A {
    func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRequireFailureOf otherGestureRecognizer: UIGestureRecognizer) -> Bool {
        print("abcd") // BREAKPOINT NOT REACHABLE
    }
}

The only thing worked is subclassing A:

class B: A {
    func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRequireFailureOf otherGestureRecognizer: UIGestureRecognizer) -> Bool {
        print("abcd") // Hallelujah! BREAKPOINT IS reachable
    }
}

But I have multiple views that have to be inherited from A. And this leads to copy and paste one logic for each inherited class. I don't want to repeat myself :)

Upvotes: 0

Views: 118

Answers (2)

Valentin Shamardin
Valentin Shamardin

Reputation: 3658

After all efforts I found a satisfactory solution. So, in third-party library I had

class A: UIGestureRecognizerDelegate { ... }

And either class B: A and class C: A in that library. So I hane wrote

extension A {
   func myHelperFunction(with some: Parameters) -> Bool {
      ...
   }
}

extension B {
   func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRequireFailureOf otherGestureRecognizer: UIGestureRecognizer) -> Bool {
        myHelperFunction(with some: Parameters)
    }
}

extension C {
   func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRequireFailureOf otherGestureRecognizer: UIGestureRecognizer) -> Bool {
        myHelperFunction(with some: Parameters)
    }
}

That's all. Minimum of code and self repeating.

Upvotes: 0

Mojtaba Hosseini
Mojtaba Hosseini

Reputation: 119310

If your based A class is a subclass of NSObject, you just need to conform A to the UIGestureRecognizerDelegate once:

class A: NSObject { // 👈 Should be subclass of `NSObject` or manually implement all requirements
  ... 
}

extension A: UIGestureRecognizerDelegate { ... }

Now you can implement any of UIGestureRecognizerDelegate optional functions you like inside any extension of the A you need.


Also, you can extend the protocol itself with a constraint of Self == A (only if A already conforms to UIGestureRecognizerDelegate ) like:

extension UIGestureRecognizerDelegate where Self == A { }

Upvotes: 0

Related Questions