¿Cómo puedo usar NSTimer en Swift?

Lo intenté

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

Pero, tengo un error que dice

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

Esto funcionará:

 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 } 

Para Swift 4, el método del que desea obtener el selector debe estar expuesto a Objective-C, por @objc atributo @objc debe agregar a la statement del método.

Aquí hay algunos ejemplos algo más completos actualizados para Swift 3 .

Evento repetido

Puede usar un temporizador para realizar una acción varias veces, como se ve en el siguiente ejemplo. El temporizador llama a un método para actualizar una etiqueta cada medio segundo.

enter image description here

Aquí está el código para eso:

 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)" } } 

Evento retrasado

También puede usar un temporizador para progtwigr un evento único por algún tiempo en el futuro. La principal diferencia con el ejemplo anterior es que utiliza repeats: false lugar de true .

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

El ejemplo anterior llama a un método llamado delayedAction dos segundos después de que se establece el temporizador. No se repite, pero aún puede llamar a timer.invalidate() si necesita cancelar el evento antes de que ocurra.

Notas

  • Si hay alguna posibilidad de iniciar su instancia de temporizador varias veces, asegúrese de invalidar primero la instancia del temporizador anterior. De lo contrario, perderás la referencia al temporizador y ya no podrás detenerlo. (ver esta pregunta y respuesta )
  • No use temporizadores cuando no sean necesarios. Consulte la sección de temporizadores de la Guía de eficiencia energética para aplicaciones de iOS .

Relacionado

  • Cómo trabajar con fechas y horas en Swift

Actualizado a Swift 4, aprovechando 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) } } 

A partir de iOS 10 también hay un nuevo método de fábrica de temporizador basado en bloques que es más limpio que usar el selector:

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

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) } } 

Notas

  • Necesita estar en la fila principal
  • La función de callback puede ser pública, privada, …
  • La función de callback debe ser @objc

Comprobar con:

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

Tendrá que usar el temporizador en lugar de NSTimer en Swift 3.

Aquí hay un ejemplo:

 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 } 

para swift 3 y Xcode 8.2 (es bueno tener bloques, pero si comstack para iOS9 Y quiere 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) } 

SimpleTimer (Swift 3.1)

¿Por qué?

Esta es una clase de temporizador simple en swift que te permite:

  • Temporizador con scope local
  • Chainable
  • One liners
  • Use devoluciones de llamada regulares

Uso:

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

Código:

 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() } } 

En Swift 3 algo como esto con @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() } 
 timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(createEnemy), userInfo: nil, repeats: true) 

Y crea diversión por el nombre createEnemy

 fund createEnemy () { do anything //// } 

Si inicia el método de temporizador

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

luego agréguelo al bucle utilizando el método de otro selector no se llamará

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

NOTA: si desea repetir esto, haga que las repeticiones sean verdaderas y conserve la referencia del temporizador; de lo contrario, no se invocará el método.

Si estás usando este método.

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

conserve una referencia para un uso posterior si las repeticiones son verdaderas.