The new Xcode 7.3 passing the parameter via addTarget usually works for me but in this case it's throwing the error in the title. Any ideas? It throws another when I try to change it to @objc
新的Xcode 7.3通过addTarget传递参数通常对我来说是可行的,但在这种情况下,它会在标题中抛出错误。什么好主意吗?当我试图将它改为@objc时,它会抛出另一个。
Thank you!
谢谢你!
cell.commentButton.addTarget(self, action: #selector(FeedViewController.didTapCommentButton(_:)), forControlEvents: UIControlEvents.TouchUpInside)
The selector it's calling
选择器调用
func didTapCommentButton(post: Post) {
}
3 个解决方案
#1
124
In my case the function of the selector was private
. Once I removed the private
the error was gone. Same goes for fileprivate
.
在我的例子中,选择器的函数是私有的。一旦我删除了private,错误就消失了。fileprivate也是一样。
In Swift 4
You will need to add @objc
to the function declaration. Until swift 4 this was implicitly inferred.
在Swift 4中,需要向函数声明中添加@objc。直到斯威夫特4被暗中推断。
#2
49
You need to use the @objc
attribute on didTapCommentButton(_:)
to use it with #selector
.
需要使用didTapCommentButton(_:)上的@objc属性与#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.
你说你那样做了,但你又犯了一个错误。我猜想新的错误是Post不是与Objective-C兼容的类型。如果所有的参数类型及其返回类型都与Objective-C兼容,则只能向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:
您可以通过使Post成为NSObject的子类来修复它,但这并不重要,因为didTapCommentButton(_:)的参数无论如何都不是Post。动作函数的参数是动作的发送方,那个发送方将是commentButton,这可能是一个UIButton。你应该像这样声明didTapCommentButton:
@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.
然后,您将面临这样的问题:获取与所单击的按钮对应的Post。有多种方法可以得到它。这是一个。
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:
我收集(因为您的代码是cell.commentButton)您正在设置一个表视图(或集合视图)。由于您的单元格有一个名为commentButton的非标准属性,我假设它是一个自定义的UITableViewCell子类。假设你的单元格是这样声明的后单元格
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:
然后您可以从按钮上向上走视图层次结构,找到PostCell,并从中获取post:
@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
}
#3
9
Try having the selector point to a wrapper function, which in turn calls your delegate function. That worked for me.
尝试让选择器指向包装器函数,包装器函数反过来调用委托函数。为我工作。
cell.commentButton.addTarget(self, action: #selector(wrapperForDidTapCommentButton(_:)), forControlEvents: UIControlEvents.TouchUpInside)
-
- - - - - -
func wrapperForDidTapCommentButton(post: Post) {
FeedViewController.didTapCommentButton(post)
}
#1
124
In my case the function of the selector was private
. Once I removed the private
the error was gone. Same goes for fileprivate
.
在我的例子中,选择器的函数是私有的。一旦我删除了private,错误就消失了。fileprivate也是一样。
In Swift 4
You will need to add @objc
to the function declaration. Until swift 4 this was implicitly inferred.
在Swift 4中,需要向函数声明中添加@objc。直到斯威夫特4被暗中推断。
#2
49
You need to use the @objc
attribute on didTapCommentButton(_:)
to use it with #selector
.
需要使用didTapCommentButton(_:)上的@objc属性与#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.
你说你那样做了,但你又犯了一个错误。我猜想新的错误是Post不是与Objective-C兼容的类型。如果所有的参数类型及其返回类型都与Objective-C兼容,则只能向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:
您可以通过使Post成为NSObject的子类来修复它,但这并不重要,因为didTapCommentButton(_:)的参数无论如何都不是Post。动作函数的参数是动作的发送方,那个发送方将是commentButton,这可能是一个UIButton。你应该像这样声明didTapCommentButton:
@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.
然后,您将面临这样的问题:获取与所单击的按钮对应的Post。有多种方法可以得到它。这是一个。
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:
我收集(因为您的代码是cell.commentButton)您正在设置一个表视图(或集合视图)。由于您的单元格有一个名为commentButton的非标准属性,我假设它是一个自定义的UITableViewCell子类。假设你的单元格是这样声明的后单元格
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:
然后您可以从按钮上向上走视图层次结构,找到PostCell,并从中获取post:
@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
}
#3
9
Try having the selector point to a wrapper function, which in turn calls your delegate function. That worked for me.
尝试让选择器指向包装器函数,包装器函数反过来调用委托函数。为我工作。
cell.commentButton.addTarget(self, action: #selector(wrapperForDidTapCommentButton(_:)), forControlEvents: UIControlEvents.TouchUpInside)
-
- - - - - -
func wrapperForDidTapCommentButton(post: Post) {
FeedViewController.didTapCommentButton(post)
}