添加UIButton目标时,"classname没有成员函数名"

Pek*_*ica 16 swift swift3

这里是Swift和iOS开发的超级新手.

我正在按照本教程关于在单个视图iOS应用程序中实现自定义控件.这是一个Swift 2教程,但到目前为止,我正在将所有内容转换为3(我使用XCode 8 Beta).

我有一个自定义类,RatingControl连接到View故事板中的一个.

在类的构造函数中,我创建了一个按钮:

let button = UIButton(frame: CGRect(x: 0, y: 0, width: 44, height: 44))
button.backgroundColor = UIColor.red()
Run Code Online (Sandbox Code Playgroud)

然后,我尝试为按钮分配一个动作.教程说我应该这样做:

button.addTarget(self, action: #selector(RatingControl.ratingButtonTapped(_:)), 
for: .touchDown)       
Run Code Online (Sandbox Code Playgroud)

然后在同一个RatingControl类中创建方法:

func ratingButtonTapped(button: UIButton) {
  print("Button pressed ")
}
Run Code Online (Sandbox Code Playgroud)

但是当我编译时,它会抱怨:

类型"RatingControl"没有成员"ratingButtonTapped"

我已经100%确定函数在那里,在类中,并正确命名.完整来源

有什么明显的东西我不见了吗?

我尝试了什么:

  • @objc根据这个答案添加到类定义中(但对于仅限Swift的东西,这似乎很奇怪,不是吗?)

  • ratingButtonTapped()明确制作public(但看起来不应该是必要的)

  • 摆弄字符串而不是选择器,button.addTarget(self, action: "RatingControl.ratingButtonTapped", for: .touchDown)还有更多,但这只会在以后崩溃.

OOP*_*Per 16

在Swift 3中,方法参考:func ratingButtonTapped(button: UIButton)成为ratingButtonTapped(button:).

所以,使用#selector(RatingControl.ratingButtonTapped(button:))也工作.

如果你想保留#selector(RatingControl.ratingButtonTapped(_:)),那么你需要将ratingButtonTapped方法声明为:

func ratingButtonTapped(_ button: UIButton) { //<- `_`
    print("Button pressed ")
}
Run Code Online (Sandbox Code Playgroud)

如果ratingButtonTapped类中只有一个方法,则可以#selector(RatingControl.ratingButtonTapped)简单地(从RatingControl类内部)对选择器进行寻址#selector(ratingButtonTapped).


vac*_*ama 11

发生这种情况是因为Swift 3改变了处理第一个参数名称的方式.在Swift 3中,除非将explicit _声明为参数名称,否则在调用函数时必须使用所有参数名称.

如果你宣布你的函数为:你用作你的选择器就好了:

func ratingButtonTapped(_ button: AnyObject) {
    print("Button pressed ")
}
Run Code Online (Sandbox Code Playgroud)

你也可以用它作为你的选择器:

#selector(RatingControl.ratingButtonTapped(button:))
Run Code Online (Sandbox Code Playgroud)

根据这个答案将@objc添加到类定义中(但对于仅限Swift的东西,这似乎很奇怪,不是吗?)

您的代码可能在Swift中,但在编写Cocoa Touch(iOS框架)时,您正在与Objective-C运行时进行交互.的选择器是必须的Objective-C运行可见的功能.你大部分时间都可以免费获得这个,因为你是在一个最终继承自NSObject(类似UIViewController)的类中实现它.如果你有一个不继承的Swift类NSObject,那么你可以添加@objc使类和方法对Objective-C运行时可见.