'#selector' refers to a method that is not exposed to Objective-C
In my case the function of the selector was private
. Once I removed the private
the error was gone. Same goes for fileprivate
.
In Swift 4
You will need to add @objc
to the function declaration. Until swift 4 this was implicitly inferred.
You need to use the @objc
attribute on didTapCommentButton(_:)
to use it with #selector
.
You say you did that but you got another error. My guess is that the new error is that Post
is not a type that is compatible with Objective-C. You can only expose a method to Objective-C if all of its argument types, and its return type, are compatible with Objective-C.
You could fix that by making Post
a subclass of NSObject
, but that's not going to matter, because the argument to didTapCommentButton(_:)
will not be a Post
anyway. The argument to an action function is the sender of the action, and that sender will be commentButton
, which is presumably a UIButton
. You should declare didTapCommentButton
like this:
@objc func didTapCommentButton(sender: UIButton) {
// ...
}
You'll then face the problem of getting the Post
corresponding to the tapped button. There are multiple ways to get it. Here's one.
I gather (since your code says cell.commentButton
) that you're setting up a table view (or a collection view). And since your cell has a non-standard property named commentButton
, I assume it's a custom UITableViewCell
subclass. So let's assume your cell is a PostCell
declared like this:
class PostCell: UITableViewCell {
@IBOutlet var commentButton: UIButton?
var post: Post?
// other stuff...
}
Then you can walk up the view hierarchy from the button to find the PostCell
, and get the post from it:
@objc func didTapCommentButton(sender: UIButton) {
var ancestor = sender.superview
while ancestor != nil && !(ancestor! is PostCell) {
ancestor = view.superview
}
guard let cell = ancestor as? PostCell,
post = cell.post
else { return }
// Do something with post here
}