Calling a Protocol Function from A Selector in Swift
Asked Answered
C

1

6

I have a protocol that acts as a delegate between one view and another.

The protocol looks (something like) this:

protocol MyProtocol: class {
    func functionOne()
}

And the protocol is implemented in View2 with something like:

extension View2:MyProtocol {
    func functionOne() {
        print("Hello World"
    }
}

Now I want this method to be called by the target of a button in View1. Therefore in View1 I have a line:

myButton(self, action: #selector(delegate?.functionOne), forControlEvents: .TouchUpInside)

But the button line errors with "Use of unresolved identifier 'functionOne'", which is an error I haven't seen before in other questions.

Everything works if I make a functionTwo in View1 and set the target to functionTwo, and then implement functionTwo by directly calling delegate?.functionOne. But that seems very inelegant.

Countess answered 16/7, 2016 at 2:25 Comment(1)
Possible duplicate of Swift 2.2 #selector in protocol extension compiler errorRibosome
S
6
@objc
protocol MyProtocol: class {
    func functionOne()
}


button.addTarget(self, action: #selector(MyProtocol.functionOne), for: .touchUpInside)

The above syntax doesn't care where the protocol is implemented. It only cares about the name of the function and its signature. Because of this behaviour, we say MyProtocol.functionOne and that tells it enough. Some class conforms to that and implements a function with that signature and name.

Sightseeing answered 16/7, 2016 at 3:8 Comment(4)
Please note that you will crash if self does not implement functionOne.Sinistral
@Sinistral wait, "if self does not implement functionOne"? Don't you mean if the MyProtocol class doesn't implement functionOne? The whole point of using delegation is that self purposefully does not implement functionOne.Countess
I don't care about delegation. I'm just cautioning you to be careful. You are saying "send functionOne message to self". So self must be have a functionOne implementation or you will crash when that happens. Try it and see.Sinistral
just replace target value (self) with your implementation of protocol (delegate)Willianwillie

© 2022 - 2024 — McMap. All rights reserved.