Swift和iOS开发中的超级新手。
我正在关注this tutorial关于在单个视图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()
然后,我尝试为按钮指定一个动作。教程说我应该这样做:
button.addTarget(self, action: #selector(RatingControl.ratingButtonTapped(_:)),
for: .touchDown)
然后在同一个RatingControl
类中创建方法:
func ratingButtonTapped(button: UIButton) {
print("Button pressed ")
}
但是当我编译时,它会抱怨:
type" RatingControl"没有会员" ratingButtonTapped"
我已经100%确定该功能在课堂上,并且正确命名。 Full source
我有什么明显的遗失吗?
我尝试了什么:
根据this answer将@objc
添加到类定义中(但对于仅限Swift的东西,似乎很奇怪,不是吗?)
明确制作ratingButtonTapped()
public
(但这看起来不应该是必要的)
摆弄字符串而不是选择器,button.addTarget(self, action: "RatingControl.ratingButtonTapped", for: .touchDown)
等等,但这只会在以后崩溃。
答案 0 :(得分:16)
在Swift 3中,func ratingButtonTapped(button: UIButton)
的方法参考变为ratingButtonTapped(button:)
。
因此,使用#selector(RatingControl.ratingButtonTapped(button:))
也可以。
如果您想保留#selector(RatingControl.ratingButtonTapped(_:))
,则需要将ratingButtonTapped
方法声明为:
func ratingButtonTapped(_ button: UIButton) { //<- `_`
print("Button pressed ")
}
如果您在课程中只有一个ratingButtonTapped
方法,则可以将选择器设置为#selector(RatingControl.ratingButtonTapped)
或简单地(来自RatingControl
类内)#selector(ratingButtonTapped)
。
答案 1 :(得分:11)
这是因为 Swift 3 改变了处理第一个参数名称的方式。在 Swift 3 中,除非将明确的_
声明为参数名称,否则在调用函数时必须使用所有参数名称。
如果你宣布你的功能为:
,你用作选择器的方法很好func ratingButtonTapped(_ button: AnyObject) {
print("Button pressed ")
}
您也可以将此作为选择器使用:
#selector(RatingControl.ratingButtonTapped(button:))
根据这个答案将@objc添加到类定义中(但似乎如此 对于Swift唯一的东西很奇怪,不是吗?)
您的代码可能在Swift中,但在编写 Cocoa Touch (iOS框架)时,您正在与Objective-C运行时进行交互。 选择器是一个需要对Objective-C运行时可见的函数。您大部分时间都是免费获得这个,因为您在最终继承自NSObject
的类中实现了这一点(如UIViewController
)。如果您只有一个不从NSObject
继承的Swift类,那么您可以添加@objc
以使类和方法对Objective-C运行时可见。
答案 2 :(得分:3)
如果要从不同的类调用View Controller中的操作,可以尝试此操作。
将ViewController()用于目标。使用ViewController.functionName作为选择器。不要像“vc”那样对视图控制器变量使用辅助方法,否则您将无法访问ViewController中的对象。
以下是一个示例目标:
self.addTarget(ViewController(), action:#selector(ViewController.Test(_:)), for: UIControlEvents.touchDragInside)
在View Controller中,这是一个示例Action
@IBAction func Test(_ sender: Any?) {
print("Goodtime was here")
}
在目标中,您必须添加()但不能在操作的选择器中添加。你不必调用@IBAction,它可以只是func。有些人使用@objc或public,这些前缀中的任何一个都应该有效。
检查,如果操作位于不同的Class或ViewController中,则必须将Class引用放在目标和操作的选择器中。否则,无论选择器中的操作是否正确,它都会尝试始终在同一文件中调用操作。同样,如果操作在同一个文件中,则为目标和操作选择器内部使用self。
干杯
答案 3 :(得分:2)
首先在swift 3中添加按钮目标时,您需要位于class
。
class SomeClass {
// ...
let button = UIButton()
// configure button to taste...
button.addTarget(self,
action: #selector(doSomething),
for: .touchUpInside)
// ...
@objc public func doSomething() {
print("hello, world!")
}
// ...
}