У меня есть класс (class A: UIView), соответствующий протоколу UIGestureRecognizerDelegate из сторонней библиотеки. Мне нужно расширить этот класс, добавив необязательный метод UIGestureRecognizerDelegate, например gestureRecognizer:shouldRequireFailureOfGestureRecognizer:. Как это сделать?
Я попробовал написать расширение для A:
extension A {
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRequireFailureOf otherGestureRecognizer: UIGestureRecognizer) -> Bool {
print("abcd") // BREAKPOINT NOT REACHABLE
}
}
Затем расширение протокола (даже без Self == A):
extension UIGestureRecognizer where Self == A {
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRequireFailureOf otherGestureRecognizer: UIGestureRecognizer) -> Bool {
print("abcd") // BREAKPOINT NOT REACHABLE
}
}
Единственное, что сработало, это создание подкласса A:
class B: A {
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRequireFailureOf otherGestureRecognizer: UIGestureRecognizer) -> Bool {
print("abcd") // Hallelujah! BREAKPOINT IS reachable
}
}
Но у меня есть несколько представлений, которые нужно унаследовать от A. А это приводит к копированию и вставке одной логики для каждого унаследованного класса. Не хочу повторяться :)
@Sweeper Существует немного более сложная структура наследования. C->B->A в библиотеке модулей. В редактируемом коде я наследуюсь от C, но соответствие протоколу реализовано в B. Чертовы сторонние библиотеки
В Swift это невозможно, в Swift нужно будет искать обходные пути: использовать обертки протоколов например. Но на самом деле это не класс Swift и не протокол Swift, поэтому вы можете использовать swizzling Objective-C.





Если ваш базовый класс A является подклассом NSObject, вам просто нужно один раз привести A в соответствие с UIGestureRecognizerDelegate:
class A: NSObject { // 👈 Should be subclass of `NSObject` or manually implement all requirements
...
}
extension A: UIGestureRecognizerDelegate { ... }
Теперь вы можете реализовать любую из UIGestureRecognizerDelegate дополнительных функций, которые вам нравятся, внутри любого расширения A, которое вам нужно.
Кроме того, вы можете расширить сам протокол, добавив ограничение Self == A (только если A уже соответствует UIGestureRecognizerDelegate ), например:
extension UIGestureRecognizerDelegate where Self == A { }
После всех усилий я нашел удовлетворительное решение. Итак, в сторонней библиотеке у меня было
class A: UIGestureRecognizerDelegate { ... }
И либо class B: A и class C: A в этой библиотеке.
Итак, я написал
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)
}
}
Вот и все. Минимум кода и самоповторяющихся.
Вам не нужно будет копировать и вставлять. Просто сделайте так, чтобы ваши представления наследовались от
BвместоA.