我如何使用定时器(以前的NSTimer)在Swift?

我试着

var timer = NSTimer()
timer(timeInterval: 0.01, target: self, selector: update, userInfo: nil, repeats: false)

但是,我得到了一个错误

'(timeInterval: $T1, target: ViewController, selector: () -> (), userInfo: NilType, repeats: Bool) -> $T6' is not identical to 'NSTimer'
380950 次浏览

检查:

斯威夫特2

var timer = NSTimer.scheduledTimerWithTimeInterval(0.01, target: self, selector: Selector("update"), userInfo: nil, repeats: true)

斯威夫特,3,4,5

var timer = Timer.scheduledTimer(timeInterval: 0.01, target: self, selector: #selector(self.update), userInfo: nil, repeats: true)

这是可行的:

override func viewDidLoad() {
super.viewDidLoad()
// Swift block syntax (iOS 10+)
let timer = Timer(timeInterval: 0.4, repeats: true) { _ in print("Done!") }
// Swift >=3 selector syntax
let timer = Timer.scheduledTimer(timeInterval: 0.4, target: self, selector: #selector(self.update), userInfo: nil, repeats: true)
// Swift 2.2 selector syntax
let timer = NSTimer.scheduledTimerWithTimeInterval(0.4, target: self, selector: #selector(MyClass.update), userInfo: nil, repeats: true)
// Swift <2.2 selector syntax
let timer = NSTimer.scheduledTimerWithTimeInterval(0.4, target: self, selector: "update", userInfo: nil, repeats: true)
}


// must be internal or public.
@objc func update() {
// Something cool
}

对于Swift 4,你想要获取选择器的方法必须暴露在Objective-C中,因此@objc属性必须添加到方法声明中。

重复的事件

您可以使用计时器多次执行一个操作,如下面的示例所示。计时器每半秒调用一个方法来更新一个标签。

enter image description here

下面是它的代码:

import UIKit


class ViewController: UIViewController {


var counter = 0
var timer = Timer()


@IBOutlet weak var label: UILabel!


// start timer
@IBAction func startTimerButtonTapped(sender: UIButton) {
timer.invalidate() // just in case this button is tapped multiple times


// start the timer
timer = Timer.scheduledTimer(timeInterval: 0.5, target: self, selector: #selector(timerAction), userInfo: nil, repeats: true)
}


// stop timer
@IBAction func cancelTimerButtonTapped(sender: UIButton) {
timer.invalidate()
}


// called every time interval from the timer
func timerAction() {
counter += 1
label.text = "\(counter)"
}
}

延迟事件

您还可以使用计时器将一次性事件安排到未来的某一段时间。与上面例子的主要区别是你使用repeats: false而不是true

timer = Timer.scheduledTimer(timeInterval: 2.0, target: self, selector: #selector(delayedAction), userInfo: nil, repeats: false)

上面的例子在计时器设置后两秒调用一个名为delayedAction的方法。它不会重复,但是如果你需要在事件发生之前取消它,你仍然可以调用timer.invalidate()

笔记

  • 如果有机会多次启动计时器实例,请确保先使旧的计时器实例失效。否则你会失去对计时器的引用,你就不能再停止它了。(见这Q&)
  • 不要在不需要的时候使用计时器。参见iOS应用的能源效率指南. xml文件的定时器部分。

相关的

更新到Swift 4,利用userInfo:

class TimerSample {


var timer: Timer?


func startTimer() {
timer = Timer.scheduledTimer(timeInterval: 5.0,
target: self,
selector: #selector(eventWith(timer:)),
userInfo: [ "foo" : "bar" ],
repeats: true)
}


// Timer expects @objc selector
@objc func eventWith(timer: Timer!) {
let info = timer.userInfo as Any
print(info)
}


}

在Swift 3中,你需要使用计时器而不是NSTimer。

这里有一个例子:

Timer.scheduledTimer(timeInterval: 1,
target: self,
selector: #selector(YourController.update),
userInfo: nil,
repeats: true)


// @objc selector expected for Timer
@objc func update() {
// do what should happen when timer triggers an event
}

在iOS 10中,还有一个新的基于块的定时器工厂方法,它比使用选择器更干净:

    _ = Timer.scheduledTimer(withTimeInterval: 5, repeats: false) { timer in
label.isHidden = true
}

斯威夫特3中使用@objc:

func startTimerForResendingCode() {
let timerIntervalForResendingCode = TimeInterval(60)
Timer.scheduledTimer(timeInterval: timerIntervalForResendingCode,
target: self,
selector: #selector(timerEndedUp),
userInfo: nil,
repeats: false)
}








@objc func timerEndedUp() {
output?.timerHasFinishedAndCodeMayBeResended()
}

swift 3和Xcode 8.2 (有块很好,但如果你编译为iOS9和想要userInfo):

...

        self.timer = Timer(fireAt: fire,
interval: deltaT,
target: self,
selector: #selector(timerCallBack(timer:)),
userInfo: ["custom":"data"],
repeats: true)


RunLoop.main.add(self.timer!, forMode: RunLoopMode.commonModes)
self.timer!.fire()
}


func timerCallBack(timer: Timer!){
let info = timer.userInfo
print(info)
}

Swift 3, pre iOS 10

func schedule() {
DispatchQueue.main.async {
self.timer = Timer.scheduledTimer(timeInterval: 20, target: self,
selector: #selector(self.timerDidFire(timer:)), userInfo: nil, repeats: false)
}
}


@objc private func timerDidFire(timer: Timer) {
print(timer)
}

Swift 3, iOS 10+

DispatchQueue.main.async {
self.timer = Timer.scheduledTimer(withTimeInterval: 20, repeats: false) { timer in
print(timer)
}
}

笔记

  • 它需要在主队列上
  • 回调函数可以是public, private,…
  • 回调函数需要@objc

如果你init定时器的方法

let timer = Timer(timeInterval: 3, target: self, selector: #selector(update(_:)), userInfo: [key : value], repeats: false)


func update(_ timer : Timer) {


}

然后将它添加到循环中,使用方法other selector将不会被调用

RunLoop.main.add(timer!, forMode: .defaultRunLoopMode)

注意:如果你想要这个重复,使重复为真,并保持定时器的引用,否则更新方法将不会被调用。

如果你使用这种方法。

Timer.scheduledTimer(timeInterval: seconds, target: self, selector: #selector(update(_:)), userInfo: nil, repeats: true)

如果repeat为真,则保留一个参考供以后使用。

SimpleTimer (Swift 3.1)

为什么?

这是一个简单的定时器类在swift,使您能够:

  • 局部作用域定时器
  • 证明
  • 一个衬垫
  • 使用常规回调

用法:

SimpleTimer(interval: 3,repeats: true){print("tick")}.start()//Ticks every 3 secs

代码:

class SimpleTimer {/*<--was named Timer, but since swift 3, NSTimer is now Timer*/
typealias Tick = ()->Void
var timer:Timer?
var interval:TimeInterval /*in seconds*/
var repeats:Bool
var tick:Tick


init( interval:TimeInterval, repeats:Bool = false, onTick:@escaping Tick){
self.interval = interval
self.repeats = repeats
self.tick = onTick
}
func start(){
timer = Timer.scheduledTimer(timeInterval: interval, target: self, selector: #selector(update), userInfo: nil, repeats: true)//swift 3 upgrade
}
func stop(){
if(timer != nil){timer!.invalidate()}
}
/**
* This method must be in the public or scope
*/
@objc func update() {
tick()
}
}
timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(createEnemy), userInfo: nil, repeats: true)

通过createEnemy这个名字创造乐趣

fund createEnemy ()
{
do anything ////
}
在Swift 4.2中,NSTimer已被重命名为Timer。 这个语法将在4.2中工作:

let timer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(UIMenuController.update), userInfo: nil, repeats: true)

斯威夫特5

我个人更喜欢带块闭包的定时器:

    Timer.scheduledTimer(withTimeInterval: 1, repeats: false) { (_) in
// TODO: - whatever you want
}

首先声明你的计时器

var timer: Timer?

然后在viewDidLoad()或任何你想要启动计时器的函数中添加line

timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(action), userInfo: nil, repeats: false)

这是func,你将回调它来做一些事情它必须是@objc

@objc func action () {
print("done")
}

我试着在一个NSObject类,这为我工作:

DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(300)) {
print("Bang!") }