我试图在Swift中创建一个NSTimer,但我遇到了一些麻烦。
NSTimer(timeInterval: 1, target: self, selector: test(), userInfo: nil, repeats: true)
Test()是同一个类中的一个函数。
我在编辑器中得到一个错误:
无法找到一个超载的'init'接受提供的
参数
当我把selector: test()改为selector: nil时,错误就消失了。
我试过了:
选择器:测试()
选择器:测试
选择器:选择器(测试())
但是什么都没用,我在参考文献中找不到解决方案。
创建如下所示的选择器。
1.
UIBarButtonItem(
title: "Some Title",
style: UIBarButtonItemStyle.Done,
target: self,
action: "flatButtonPressed"
)
2.
flatButton.addTarget(self, action: "flatButtonPressed:", forControlEvents: UIControlEvents.TouchUpInside)
注意,@selector语法消失了,取而代之的是一个简单的String来命名要调用的方法。有一个方面,我们都同意冗长是一个障碍。当然,如果我们声明有一个名为flatButtonPressed的目标方法:我们最好写一个:
func flatButtonPressed(sender: AnyObject) {
NSLog("flatButtonPressed")
}
设置定时器:
var timer = NSTimer.scheduledTimerWithTimeInterval(1.0,
target: self,
selector: Selector("flatButtonPressed"),
userInfo: userInfo,
repeats: true)
let mainLoop = NSRunLoop.mainRunLoop() //1
mainLoop.addTimer(timer, forMode: NSDefaultRunLoopMode) //2 this two line is optinal
为了完整,这里是flatButtonPressed
func flatButtonPressed(timer: NSTimer) {
}
如果你想从NSTimer中传递一个参数给函数,那么这里是你的解决方案:
var somethingToPass = "It worked"
let timer = NSTimer.scheduledTimerWithTimeInterval(0.01, target: self, selector: "tester:", userInfo: somethingToPass, repeats: false)
func tester(timer: NSTimer)
{
let theStringToPrint = timer.userInfo as String
println(theStringToPrint)
}
在选择器文本(tester:)中包含冒号,参数则放在userInfo中。
你的函数应该以NSTimer作为参数。然后提取userInfo以获得传递的参数。
Swift 2.2+和Swift 3更新
使用新的#selector表达式,它消除了使用字符串文字的需要,使使用更不容易出错。供参考:
Selector("keyboardDidHide:")
就变成了
#selector(keyboardDidHide(_:))
参见:快速进化提案
注意(Swift 4.0):
如果使用# selector,你需要将函数标记为@objc
例子:
@objc func something(_ sender: UIButton)
// for swift 2.2
// version 1
buttton.addTarget(self, action: #selector(ViewController.tappedButton), forControlEvents: .TouchUpInside)
buttton.addTarget(self, action: #selector(ViewController.tappedButton2(_:)), forControlEvents: .TouchUpInside)
// version 2
buttton.addTarget(self, action: #selector(self.tappedButton), forControlEvents: .TouchUpInside)
buttton.addTarget(self, action: #selector(self.tappedButton2(_:)), forControlEvents: .TouchUpInside)
// version 3
buttton.addTarget(self, action: #selector(tappedButton), forControlEvents: .TouchUpInside)
buttton.addTarget(self, action: #selector(tappedButton2(_:)), forControlEvents: .TouchUpInside)
func tappedButton() {
print("tapped")
}
func tappedButton2(sender: UIButton) {
print("tapped 2")
}
// swift 3.x
button.addTarget(self, action: #selector(tappedButton(_:)), for: .touchUpInside)
func tappedButton(_ sender: UIButton) {
// tapped
}
button.addTarget(self, action: #selector(tappedButton(_:_:)), for: .touchUpInside)
func tappedButton(_ sender: UIButton, _ event: UIEvent) {
// tapped
}
当使用performSelector()时
/addtarget()/NStimer.scheduledTimerWithInterval()方法你的方法(匹配选择器)应该被标记为
@objc
For Swift 2.0:
{
//...
self.performSelector(“performMethod”, withObject: nil , afterDelay: 0.5)
//...
//...
btnHome.addTarget(self, action: “buttonPressed:", forControlEvents: UIControlEvents.TouchUpInside)
//...
//...
NSTimer.scheduledTimerWithTimeInterval(0.5, target: self, selector : “timerMethod”, userInfo: nil, repeats: false)
//...
}
@objc private func performMethod() {
…
}
@objc private func buttonPressed(sender:UIButton){
….
}
@objc private func timerMethod () {
….
}
对于Swift 2.2,
你需要写“#selector()”而不是字符串和选择器名称,这样拼写错误和崩溃的可能性就不会再存在了。下面是示例
self.performSelector(#selector(MyClass.performMethod), withObject: nil , afterDelay: 0.5)