У меня есть класс (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
.