4

Я пытаюсь создать протокол, который будет реализован определенными классами, все они также должны реализовать UIScrollViewDelegate. Я думал о том, что для моего нового протокола используется протокол UIScrollViewDelegate.По умолчанию реализация протокола протокола

protocol MyProtocol: UIScrollViewDelegate { 
    var myVar: NSString { get } 
    func myMethod() 
} 

Поскольку протокол должен иметь свою реализацию по умолчанию, я также создал расширение для этого протокола.

extension MyProtocol { 
    func myMethod() { 
     print("I'm printing") 
    } 

    func scrollViewDidScroll(scrollView: UIScrollView) { 
     print("I'm scrollin") 
    } 
} 

Он компилируется, но не работает. Что я делаю неправильно и что будет правильным способом создать стандартную реализацию расширенного протокола?

+0

Я думаю, что вы на правильном пути. Я предполагаю, что вам нужно переопределить сеттер для делегата в вашем протоколе и вызвать super.delegate = theDelegate –

+1

Что значит «это не работает». Что происходит? Это не приемлемое описание проблемы. – nhgrif

+0

На первый взгляд вы на правильном пути, но с Swift 2.2 методы делегата, определенные в расширениях протокола, не «найдены» из кода Objective-C. Вам необходимо расширить класс, который соответствует 'UIScrollViewDelegate', который определяет метод расширения' scrollViewDidScroll' в конкретном классе 'MyScrollViewDelegate' или' MyScrollViewViewController'. – CouchDeveloper

ответ

5

То, что вы хотите сделать, это следующее:

protocol MyProtocol{ 
    var myVar: NSString { get } 
    func myMethod() 
} 

protocol MyProtocol2{ 
    var myVar2: NSString { get } 
    func myMethod2() 
} 

extension MyProtocol where Self: MyProtocol2 { 
    func myMethod() { 
     print("I'm printing ") 
    } 
} 

class anotherClass: MyProtocol, MyProtocol2 { 
    var myVar: NSString { 
     return "Yo" 
    } 

    var myVar2: NSString { 
     return "Yo2" 
    } 

    func myMethod2() { 
     print("I'm printing in myMethod2") 
    } 
} 

В приведенном выше коде MyProtocol2 эквивалентно вашему UIScrollViewDelegate,

значит, что вы будете делать это:

protocol MyProtocol{ 
    var myVar: NSString { get } 
    func myMethod() 
} 

extension MyProtocol where Self: UIScrollViewDelegate { 
    func myMethod() { 
     print("I'm printing") 
    } 
} 

class anotherClass: NSObject, MyProtocol, UIScrollViewDelegate { 
    var myVar: NSString { 
     return "Yo" 
    } 
} 

Примечание что другой класс подклассов NSObject, это потому, что, если вы этого не сделаете, вы получите сообщение об ошибке

anotherClass не соответствует протоколу NSObjectProtocol

Эта ошибка происходит потому, что само по себе UIScrollViewDelegate определяется быть расширение NSObjectProtocol, который представляет собой протокол Objective-C реализуется NSObject.

Так что сделайте свой класс наследованным от NSObject для соответствия NSObjectProtocol. Классы Vanilla Swift - нет.

+0

Я хочу перенести реализацию этих функций из тела класса, так как она должна действовать одинаково в каждом классе, реализующем протокол. Я знаю, что это не то, для чего предназначены протоколы, но я хочу создать расширение протокола с реализацией метода из другого протокола (который реализуется основным). –

+0

да, вы все еще можете реализовать методы UIScrollViewDelegate в расширении протокола. – uchiha

+0

Спасибо за ответ @uchiha Я пробовал делать это для того, где 'anotherClass' является подклассом' UIViewController', который уже является потомком 'NSObject', но функция 'scrollViewDidScroll (_ scrollView: UIScrollView)' в 'UIScrollViewDelegate' некорректно переопределена. Похоже, я добавил еще одну версию 'scrollViewDidScroll' в мой класс. Я понимаю, что с помощью описанного метода вы сможете удовлетворить один протокол функциями из другого протокола, но сможете ли вы когда-либо создать стандартную реализацию функции 'scrollViewDidScroll'? – gokeji

Смежные вопросы